Klasse bei Fehler im __construct() nicht instantiieren

ZodiacXP

Erfahrenes Mitglied
Servus.

Scheinbar nutze ich die falschen Suchbegriffe bei Google und Co.

Weiß jemand wie man das intantiieren einer Klasse im Konstruktor verhindern kann bzw. statt einem neuen Objekt ein false oder NULL entsteht?

Beispiel:
PHP:
class Mensch
{
  function __construct($geschlecht)
  {
    if ($geschlecht != 'm' && $geschlecht != 'w' && $geschlecht != 'i')
    {
      $this->__destruct(); // Hier solls verhindert werden
    }
  }
}

Edit: Wirklich im Konstruktor - kein Pattern wie z.B. Factory soll verwendet werden.
 
Zuletzt bearbeitet:
Warum prüfst du den Wert nicht, bevor du eine Instance der Klasse erstellst/einbindest?


PHP:
$g = array('m', 'w', 'i');
if (in_array($geschlecht, $g))
{
	$m = new mensch($geschlecht);
}
else
{
	// mach irgendwas
}
 
Einfache Antwort passend zum Beispiel: Stell dir vor das muss man für jeden Menschen einzeln machen ;)
Hab das eigentliche Problem anders gelöst, aber leider geht es nur über Exceptions,
 
Hi,

Einfache Antwort passend zum Beispiel: Stell dir vor das muss man für jeden Menschen einzeln machen
Dann schreib dir halt eine Funktion, der du das Geschlecht uebergibst und die dir im Erfolgsfall eine Instanz der Klasse Mensch zurückliefert.

Ich halte den Vorschlag von bofh1337 auch für klüger, zumal Exceptions in Konstruktoren vermieden werden sollten. Und wirklich logisch erscheint mir der Ansatz auch nicht. Warum sollte die Klasse zunächst selbst überprüfen, ob von ihr wirklich ein Objekt erzeugt werden darf!?

Edit: Wirklich im Konstruktor - kein Pattern wie z.B. Factory soll verwendet werden.
Eine Fabrik würde ich für angebracht halten. Kannst du erklären, warum du darauf verzichten möchtest/musst?

Gruß
 
Exceptions sind nicht zum vermeiden. Exceptions können sauber abgefangen und behandelt werden. Es ist ja nicht so dass gleich eine unschöne Fehlermeldung ausgegeben werden muss.
PHP verleitet zwar dazu das ganze Exception-Handling wegzulassen, jedoch ist dies eine sehr mächtige Sache um sauber zu programmieren.

Ansonsten kann man grad in diesem Beispiel mit Enums arbeiten. Gut, PHP stellt selber keine Enums zur Verfügung, ich aber schon *g*
http://wiki.yaslaw.info/wikka/PhpEnums

PHP:
<?php
//Fehler zu Eyxceptions umleiten
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");

//Enum einbinden
require_once('tools/lib/enum/Enum.php');

//Enum m/w erstellen
Enum::create('Sex', 'm', 'w');

// Die Klasse
class Mensch{
    //Der Parameter muss vom Type Sex sein
    function __construct(Sex $geschlecht){}
} 

try{
    //Parameter ist ein Enum vom Typ 'Sex'
    $sex = Sex::w();
    $eva = new Mensch($sex);
    //Parameter ist ein Enum vom Typ 'Sex'
    $sex = 'm';
    $hans = new Mensch(Sex::getEnum($sex));    
    //Parameter ist kein Enum vom Typ 'Sex'
    $sex = 'hund';
    $waldi = new Mensch($sex);
} catch (Exception $e){
    echo "{$sex} is not a valid Enum of 'Sex'";
}
?>
 
Eine Fabrik würde ich für angebracht halten. Kannst du erklären, warum du darauf verzichten möchtest/musst?



Usability ;) Werde nicht der einzige sein, der die Klasse nutzt. Neulinge sollen net gleich überfordert und abgeschreckt werden durch komplexe Lösungen.
Hab einen komplett anderen Weg genommen bei dem alles gewohnte Wege geht. Wird zwar noch eine Klasse instantiiert aber da sie von Iterator erbt ist func valid() sowieso enthalten und nutzbar.

Statt "if ($o)" wird also "if ($o->valid())" verwendet. Schlicht und relativ leicht. Leichter wäre nur noch wenn man das erste irgendwie hinkriegt ;)
Kleiner Abstrich in Usability aber IMHO die angenehmste Lösung.
 
Usability ;) Werde nicht der einzige sein, der die Klasse nutzt. Neulinge sollen net gleich überfordert und abgeschreckt werden durch komplexe Lösungen.
Hab einen komplett anderen Weg genommen bei dem alles gewohnte Wege geht. Wird zwar noch eine Klasse instantiiert aber da sie von Iterator erbt ist func valid() sowieso enthalten und nutzbar.

Statt "if ($o)" wird also "if ($o->valid())" verwendet. Schlicht und relativ leicht. Leichter wäre nur noch wenn man das erste irgendwie hinkriegt ;)
Kleiner Abstrich in Usability aber IMHO die angenehmste Lösung.

Wenn man allerdings das Validieren der Eingaben etwas genauer nimmt, kann man sich den ganzen Kram auch sparen.

Ich würde dann zb. das Select so gestalten, das wenn nichts ausgewählt wurde, zb. das "i" als Default übergeben wird, damit hätte ich zumindest ein Wert, womit ich in der Klasse arbeiten kann und könnte mir den ganzen Kram mit Exceptions und Anweisungen usw. sparen.
 
Zurück