Sven Rautenberg: OOP php: verschachtelte Klassen und ein Zugriff auf eine Eigensc

Beitrag lesen

Moin!

Könnt ihr mir helfen. Ich programmiere noch nicht lange OO.

Merkt man. Dein OOP-Konzept ist ziemlich grausig!

WENN du OOP machen willst, dann wende unbedingt folgende Regeln an:

1. Der Befehl "global" ist VERBOTEN!
2. Es gilt das Verbot von "global".
3. Weiterhin ist die Verwendung von "global" UNTERSAGT!

4. Die Verwendung des Keyworts "new" ist möglichst zu vermeiden.

Nachdem das also geklärt ist, wende ich mich zunächst dem auffälligsten Konstrukt deines Codes zu: Die Exceptions.

Was verstehst DU ganz persönlich unter einer Exception? Denn dein Verständnis hat sich ja irgendwie in deinem Code manifestiert, wenngleich auch nicht besonders schön. Offensichtlich verwendest du keine Exceptions im PHP-Sinn, denn wenn das der Fall wäre, würdest du sie werfen (phpthrow new Exception('Erklärtext');) und fangen (phptry { /* Code */ } catch (Exception $e) { /* Code für Fail */ }).

Alles, was du glaubst tun zu müssen, um mit Exceptions in deinem Verständnis umzugehen, ist vermutlich falsch, weil du es nicht besser kennst - aber da werden wir sicher diverse Hinweise liefern, um das zu ändern.

Ich habe ähnliche Situation vorliegen:

class Site{

var $Exception = array();

public function __construct(){

$db = new DB();

}

}

class DB{

//so sieht der exception handler aus
  //wenn einer fehler auftritt, wird die Exception an die Seite übergeben
  private function ExceptionHandler($e){

Global Site;     Site->Exception[] = $e;

}

}

// instantiierung einer Seite
$Site = new Site();

  
An deinem Code ist, wie du dir denken kannst, einiges grausam schlecht designt. Die Tatsache, dass die Site ihren DB-Handler selbst instanziiert, ist problematisch; würde ich nicht so machen, sondern als Parameter dem Konstruktor übergeben, also außerhalb der Site in dem Code, der Site ins Leben ruft.  
  
Das hat auch den Vorteil, dass du dir auf dieser einfachen Stufe direkt das GLOBAL in der DB sparen kannst, wenn du dir eine Methode `phppublic function setSiteObject(Site $site) { $this->_site = $site }` baust, dir eine private Eigenschaft $\_site für dein Site-Objekt in die DB tust, und dort dein Site-Objekt übergibst:  
  
~~~php
$db = new DB();  
$site = new Site($db);  
$db->setSiteObject($site);

In der DB hast du dann statt $Site immer $this->_site verfügbar.

Allerdings: Dein Exception-Handling ist, wie erwähnt, sehr fragwürdig.

Einen solchen ExceptionHandler() habe ich in vielen Klassen eingebaut und normalerweise klappt das mit dem Global und dem Anhängen der Exception an den Array. Nur nicht, wenn es im Konstruktor der Site geschieht. Logisch: denn dann ist das Objekt $Site noch nicht vorhanden.

Wie kann ich das lösen. Vielleicht ist der Ansatz schlecht mit dem Global aber ich möchte alle Exception an die Seite delegieren.

Ich kann dir schwerlich was raten, wenn ich nicht weiß, was du warum gemacht hast. Wirfst du Exceptions? Wo? Und was soll das Ergebnis sein, wenn eine geworfen wird.

Exceptions sind, wenn man es böse betrachtet, eine moderne Form von GOTO. Der normale Programmablauf wird verlassen, und im catch-Teil weitergemacht. Deshalb sollte man dieses Mittel eher sparsam einsetzen, insbesondere nicht zur Steuerung des Programmflusses mißbrauchen.

Im Prinzip gibt es nur zwei Möglichkeiten, mit Exceptions umzugehen: Entweder, der aufrufende Code einer exceptionwerfenden Funktion kann die Exception fangen, weil er auch mit dem Fehlerfall umzugehen weiß. Das kann beispielsweise in der Bereitstellung eines passenden Ersatzes münden (z.B.: getArrayOfDatabases() -> DbUnavailableException -> catch: return array()).

Alternativ fängt man die Exception eben gerade nicht, sondern lässt sie ganz bis nach "oben" durchschlagen - was dann natürlich nicht ganz so elegant zu einer Fehlermeldung führen würde, weshalb es eine gute Idee ist, auf oberster Codeebene ein pauschales Catch für alle Exceptions einzufügen, welcher den HTTP-Status auf 500 "Internal server error" setzt und dann noch eine hübsche Fehlerseite ausgibt.

- Sven Rautenberg