Konstruktor
__construct
(
mixed ...$values
= ""
) :
void
PHP erlaubt es Entwicklern, Konstruktormethoden für Klassen zu deklarieren.
Klassen mit Konstruktormethoden rufen diese für jedes neu erzeugte Objekt
auf, so dass Konstruktoren für alle Initialisierungen passend sind,
die das Objekt brauchen könnte bevor es benutzt wird.
Hinweis:
Konstruktoren von Vaterklassen werden nicht implizit aufgerufen, wenn die
Kindklasse einen Konstruktor definiert. Um einen Vaterkonstruktor zu benutzen
ist ein Aufruf von parent::__construct() innerhalb des
Kindkonstruktors notwendig. Falls das Kind keinen Konstruktor definiert,
dann kann er von der Vaterklasse genau wie eine normale Klassenmethode
geerbt werden (falls er nicht als privat deklariert wurde).
Beispiel #1 Konstruktoren bei der Vererbung
<?php
class BaseClass {
function __construct() {
print "Im BaseClass Konstruktor\n";
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct();
print "Im SubClass Konstruktor\n";
}
}
class OtherSubClass extends BaseClass {
// erbt den Konstruktor von BaseClass
}
// In BaseClass constructor
$obj = new BaseClass();
// In BaseClass constructor
// In SubClass constructor
$obj = new SubClass();
// In BaseClass constructor
$obj = new OtherSubClass();
?>
Im Gegensatz zu anderen Methoden, generiert PHP keinen
E_STRICT
Fehler, wenn
__construct() in einer Kindklasse
andere Parameter definiert, als die
__construct() Methode der
Elternklasse.
Konstruktoren sind gewöhnliche Methoden, die bei der Instanziierung des
entsprechenden Objekts aufgerufen werden. Als solche können sie eine
beliebige Anzahl von Argumenten definieren, die erforderlich sein können,
einen Typ haben können und einen Standardwert haben können.
Konstruktorargumente werden aufgerufen, indem die Argumente in Klammern
hinter den Klassennamen gesetzt werden.
Beispiel #2 Die Verwendung von Argumenten eines Konstruktors
<?php
class Punkt {
protected int $x;
protected int $y;
public function __construct(int $x, int $y = 0) {
$this->x = $x;
$this->y = $y;
}
}
// Beide Parameter übergeben.
$p1 = new Punkt(4, 5);
// Nur den erforderlichen Parameter übergeben. $y nimmt den Standardwert von 0 an.
$p2 = new Punkt(4);
// Mit benannten Parametern (von PHP 8.0 an):
$p3 = new Punkt(y: 5, x: 4);
?>
Wenn eine Klasse keinen Konstruktor hat oder der Konstruktor keine
erforderlichen Argumente hat, können die Klammern weggelassen werden.
Konstruktoren alten Stils
Vor PHP 8.0.0 interpretieren Klassen im globalen Namensraum eine Methode,
die den gleichen Namen wie die Klasse trägt, als Konstruktor alten Stils.
Diese Syntax ist veraltet, und führt zu einem
E_DEPRECATED
-Fehler, ruft die Funktion aber trotzdem
als Konstruktor auf. Wenn sowohl
__construct() als auch eine
Methode gleichen Namens definiert sind, wird
__construct() aufgerufen.
In Namensraum-Klassen, oder ab PHP 8.0.0 in jeder Klasse, hat eine
Methode mit dem Namen der Klasse keine besondere Bedeutung.
Verwenden Sie in neuem Code immer
__construct().
Erzeugung über statische Methoden
PHP unterstützt nur einen einzigen Konstruktor pro Klasse. In einigen
Fällen, kann es jedoch wünschenswert sein, dass ein Objekt auf
verschiedene Weisen mit unterschiedlichen Eingaben erzeugt werden kann.
Der empfohlene Weg, dies zu tun, ist die, Konstruktoren in statische
Methoden zu packen.
Beispiel #4 Die Erzeugung über statische Methoden verwenden
<?php
class Produkt {
private ?int $id;
private ?string $name;
private function __construct(?int $id = null, ?string $name = null) {
$this->id = $id;
$this->name = $name;
}
public static function fromBasicData(int $id, string $name): static {
$neu = new static($id, $name);
return $neu;
}
public static function fromJson(string $json): static {
$daten = json_decode($json);
return new static($daten['id'], $daten['name']);
}
public static function fromXml(string $xml): static {
// Hier der eigene Code.
$daten = convert_xml_to_array($xml);
$neu = new static();
$neu->id = $daten['id'];
$neu->name = $daten['name'];
return $neu;
}
}
$p1 = Produkt::fromBasicData(5, 'Widget');
$p2 = Produkt::fromJson($some_json_string);
$p3 = Produkt::fromXml($some_xml_string);
Der Konstruktor kann private oder protected gemacht werden, um zu
verhindern, dass er von außen aufgerufen wird. Wenn dies der Fall ist,
kann nur eine statische Methode die Klasse instanziieren. Da sie in der
gleichen Klassendefinition enthalten ist, hat sie Zugriff auf private
Methoden, auch wenn sie nicht zur gleichen Objektinstanz gehören. Der
private Konstruktor ist optional und kann je nach Anwendungsfall sinnvoll
sein oder nicht.
Die drei public static Methoden veranschaulichen dann verschiedene
Möglichkeiten das Objekt zu instanziieren.
fromBasicData()
nimmt genau die Parameter, die
benötigt werden, erzeugt dann das Objekt durch Aufruf des Konstruktors
und Rückgabe des Ergebnisses.
fromJson()
akzeptiert eine JSON-Zeichenkette und
führt selbst eine Vorverarbeitung durch, um sie in das vom Konstruktor
gewünschte Format zu konvertieren. Sie gibt dann das neue Objekt
zurück.
fromXml()
akzeptiert eine XML-Zeichenkette,
vorverarbeitet sie und erzeugt dann ein leeres Objekt. Der Konstruktor
wird immer noch aufgerufen, aber da alle Parameter optional sind,
überspringt sie die Methode. Sie weist dann den Objekteigenschaften
direkt Werte zu, bevor sie das Ergebnis zurückgibt.
In allen drei Fällen wird das Schlüsselwort static
in den
Namen der Klasse übersetzt, in der sich der Code befindet. In diesem
Fall: Produkt
.
Destruktor
__destruct
(
) : void
PHP 5 führt ein Destruktorkonzept ähnlich dem anderer objektorientierter
Programmiersprachen wie C++ ein. Die Destruktormethode wird aufgerufen,
sobald es keine weiteren Referenzen auf ein bestimmtes Objekt mehr gibt,
oder in beliebiger Reihenfolge am Ende des Skripts.
Beispiel #5 Destruktor Beispiel
<?php
class MyDestructableClass
{
function __construct() {
print "Im Konstruktor\n";
}
function __destruct() {
print "Zerstoere " . __CLASS__ . "\n";
}
}
$obj = new MyDestructableClass();
?>
Wie Konstruktoren auch, werden Vaterdestruktoren nicht implizit durch die
Engine aufgerufen. Um einen Vaterdestruktor zu benutzen muss man
explizit die Funktion parent::__destruct() in der
Destruktorimplementierung aufrufen. Ebenso wie Konstruktoren kann eine Kindklasse
den Destruktor des Vaters erben, falls sie keinen eigenen implementiert.
Der Destruktor wird aufgerufen, wenn das Script mittels exit()
abgebrochen wird. Wenn exit() innerhalb eines Destruktors
aufgerufen wird, verhindert das die Ausführung von jeglichen weiteren Shutdown
Routinen.
Hinweis:
Der Destruktor wird während der Skript-Abschaltung aufgerufen, weshalb die
Header immer bereits gesendet sind. Das aktuelle Verzeichnis während der
Beendigungsphase des Skripts kann bei einigen SAPIs (z.B. Apache)
ein anderes sein.
Hinweis:
Der Versuch eine Exception aus einem Destruktor (der in der Beendigungsphase
des Skripts aufgerufen wurde) heraus zu werfen wird
einen fatalen Fehler auslösen.