Magische Methoden

Die Funktionen __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() und __debugInfo() sind in PHP-Klassen magisch. Man kann keine Funktionen gleichen Namens in einer seiner Klassen haben, wenn man nicht die magische Funktionalität, die sie mit sich bringen, haben will.

Hinweis: Alle magischen Methoden müssen als public deklariert werden.

Achtung

PHP reserviert alle Funktionsnamen, die mit __ beginnen, als magisch. Es wird empfohlen, keine Funktionsnamen mit __ in PHP zu benutzen, es sei denn, man möchte dokumentierte magische Funktionalität verwenden.

__sleep() and __wakeup()

public __sleep ( void ) : array
__wakeup ( void ) : void

serialize() prüft, ob Ihre Klasse eine Funktion mit dem magischen Namen __sleep() besitzt. Wenn dem so ist, wird die Funktion vor jeder Serialisierung ausgeführt. Sie kann das Objekt aufräumen und es wird von ihr erwartet, dass sie ein Array mit den Namen aller Variablen zurückliefert, die serialisiert werden sollen. Wenn die Methode nichts zurückgibt, so wird NULL serialisiert und eine E_NOTICE geworfen.

Hinweis:

__sleep() kann nicht Namen von privaten Eigenschaften von Elternklassen zurückgeben. In diesem Fall wird eine E_NOTICE geworfen. Stattdessen sollte das Serializable Interface verwendet werden.

Die beabsichtigte Verwendung von __sleep() ist, nicht gespeicherte Daten zu sichern oder ähnliche Aufräumarbeiten zu erledigen. Die Funktion ist ebenfalls nützlich, wenn Sie sehr große Objekte haben, welche nicht komplett gespeichert werden müssen.

Umgekehrt überprüft unserialize() die Anwesenheit einer Funktion mit dem magischen Namen __wakeup(). Falls vorhanden, kann diese Funktion alle Ressourcen, die das Objekt haben könnte, wiederherstellen.

Der beabsichtigte Zweck von __wakeup() ist es, alle Datenbankverbindungen wiederherzustellen, die während der Serialisierung verloren gegangen sein könnten, oder auch andere Aufgaben zur erneuten Initialisierung.

Beispiel #1 Sleep- und Wakeup-Beispiel

<?php
class Connection
{
 protected 
$link;
 private 
$dsn$username$password;

 public function 
__construct($dsn$username$password)
 {
  
$this->dsn $dsn;
  
$this->username $username;
  
$this->password $password;
  
$this->connect();
 }

 private function 
connect()
 {
  
$this->link = new PDO($this->dsn$this->username$this->password);
 }

 public function 
__sleep()
 {
  return array(
'dsn''username''password');
 }

 public function 
__wakeup()
 {
  
$this->connect();
 }
}
?>

__toString()

public __toString ( void ) : string

Die __toString() Methode erlaubt einer Klasse zu entscheiden, wie sie reagieren soll, wenn sie in eine Zeichenkette umgewandelt wird. Die beeinflusst beispielsweise, was echo $obj; ausgeben wird. Diese Methode muss eine Zeichenkette zurückgeben, ansonsten wird ein E_RECOVERABLE_ERROR geworfen.

Warnung

Aus der Methode __toString() kann keine Exception geworfen werden. Wenn dies getan wird, so tritt ein fataler Fehler auf.

Beispiel #2 Einfaches Beispiel

<?php
// Deklariere eine einfache Klasse
class TestClass
{
 public 
$foo;

 public function 
__construct($foo)
 {
  
$this->foo $foo;
 }

 public function 
__toString()
 {
  return 
$this->foo;
 }
}

$class = new TestClass('Hallo');
echo 
$class;
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

Hallo

Es muss angemerkt werden, dass die __toString() Methode in Versionen vor PHP 5.2.0 nur in direkter Kombination mit echo oder print aufgerufen wurde. Beginnend mit PHP 5.2.0 erfolgt dieser Aufruf in jedem Stringkontext (z.B. in printf() mit %s-Platzhalter), aber in keinem der anderen Typenkontexte (z.B. mit dem %d-Platzhalter). Ebenfalls beginnend mit PHP 5.2.0 bewirkt die Umwandlung eines Objekts ohne __toString() Methode in einen String einen Fehler der Klasse E_RECOVERABLE_ERROR.

__invoke()

__invoke ([ $... ] ) : mixed

Die __invoke()-Methode wird aufgerufen, wenn ein Skript versucht, ein Objekt als Funktion aufzurufen.

Hinweis:

Dieses Feature ist ab PHP 5.3.0 verfügbar.

Beispiel #3 Nutzung von __invoke()

<?php
class CallableClass
{
 function 
__invoke($x)
 {
  
var_dump($x);
 }
}
$obj = new CallableClass;
$obj(5);
var_dump(is_callable($obj));
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

int(5)
bool(true)

__set_state()

static __set_state ( array $properties ) : object

Diese statische Methode wird seit PHP 5.1.0 für Klassen aufgerufen, die mittels var_export() exportiert werden.

Der einzige Parameter dieser Methode ist ein Array, welches aus exportierten Eigenschaften der Form array('Eigenschaft' => Wert, ...) besteht.

Beispiel #4 Verwendung von __set_state() (seit PHP 5.1.0)

<?php

class A
{
 public 
$var1;
 public 
$var2;

 public static function 
__set_state($an_array// seit PHP 5.1.0
 
{
  
$obj = new A;
  
$obj->var1 $an_array['var1'];
  
$obj->var2 $an_array['var2'];
  return 
$obj;
 }
}

$a = new A;
$a->var1 5;
$a->var2 'foo';

eval(
'$b = ' var_export($atrue) . ';'); // $b = A::__set_state(array(
           //    'var1' => 5,
           //    'var2' => 'foo',
           // ));
var_dump($b);

?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

object(A)#2 (2) {
  ["var1"]=>
  int(5)
  ["var2"]=>
  string(3) "foo"
}

Hinweis: Wenn ein Objekt exportiert wird, überprüft var_export() nicht ob __set_state() von der Objektklasse implementiert wird, so dass der erneute Import solcher Objekte fehlschlägt, falls __set_state() nicht implementiert ist. Die betrifft im Besonderen einige interne Klassen. It is the responsibility of the programmer to verify that only objects will be re-imported, whose class implements __set_state().

__debugInfo()

__debugInfo ( void ) : array

Diese Methode wird von var_dump() aufgerufen, wenn ein Objekt ausgegeben wird, um die Eigenschaften auszulesen die gezeigt werden sollen. Wenn diese Methode in einem Objekt nicht definiert ist, so werden alle Eigenschaften die public, protected oder private sind angezeigt.

Diese Feature wurde mit PHP 5.6.0 hinzugefügt.

Beispiel #5 Verwendung von __debugInfo()

<?php
class {
 private 
$prop;

 public function 
__construct($val) {
  
$this->prop $val;
 }

 public function 
__debugInfo() {
  return [
   
'propSquared' => $this->prop ** 2,
  ];
 }
}

var_dump(new C(42));
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

object(C)#1 (1) {
  ["propSquared"]=>
  int(1764)
}