Magische Methoden

Magische Methoden sind Methoden, die PHPs Standardverhalten überschreiben, wenn bestimmte Aktionen mit einem Objekt durchgeführt werden.

Achtung

Alle Methodennamen, die mit __ beginnen, sind durch PHP reserviert. Es wird daher nicht empfohlen solche Methodennamen zu verwenden, wenn man nicht PHPs Verhalten überschreiben möchte.

Die folgenden Methodennamen werden als magisch betrachtet: __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __serialize(), __unserialize(), __toString(), __invoke(), __set_state(), __clone() und __debugInfo().

Warnung

Alle magischen Methoden, mit der Ausnahme von __construct(), __destruct() und __clone(), müssen als public deklariert werden. Andernfalls wird eine E_WARNING ausgegeben. Vor PHP 8.0.0 wurde für die magischen Methoden __sleep(), __wakeup(), __serialize(), __unserialize() und __set_state() keine Diagnostik ausgegeben.

Warnung

Falls Typdeklarationen in der Definition der magischen Methoden angegeben werden, müssen diese identisch zu den Signaturen sein die in diesem Dokument beschrieben werden. Andernfalls wird ein fataler Fehler hervorgerufen. Vor PHP 8.0.0 wurde keine Diagnostik ausgegeben. Allerdings dürfen __construct() und __destruct() keinen Rückgabetyp deklarieren, sonst wird ein fataler Fehler ausgegeben.

__sleep() und __wakeup()

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

serialize() prüft, ob die 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ück liefert, die serialisiert werden sollen. Wenn die Methode nichts zurück gibt, 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 ein sehr großes Objekt nicht komplett gespeichert werden muss.

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();
    }
}
?>

__serialize() und __unserialize()

public __serialize(): array
public __unserialize(array $data): void

serialize() prüft, ob die Klasse eine Funktion mit dem magischen Namen __serialize() besitzt. Wenn dem so ist, wird die Funktion vor jeder Serialisierung ausgeführt. Sie muss ein assoziatives Array von Schlüssel/Wert-Paaren erzeugen und zurückgeben, die die serialisierte Form des Objekts darstellen. Wird kein Array zurückgegeben, wird ein TypeError geworfen.

Hinweis:

Sind sowohl __serialize() als auch __sleep() im selben Objekt definiert, wird nur __serialize() aufgerufen. __sleep() wird ignoriert. Implementiert das Objekt das Serializable Interface, wird die serialize() Methode des Interface ignoriert und __serialize() statt dessen verwendet.

Die beabsichtigte Verwendung von __serialize() ist, eine serialisierungsfreundlich beliebige Darstellung eines Objekts zu definieren. Elemente des Arrays dürfen Eigenschaften entsprechen, aber das ist nicht erforderlich.

Umgekehrt überprüft unserialize() die Anwesenheit einer Funktion mit dem magischen Namen __unserialize(). Falls vorhanden, wird dieser Funktion das wiederhergestellte Array übergeben, das von __serialize() zurückgegeben wurde. Sie kann dann dementsprechend die Eigenschaften des Objekts aus diesem Array wiederherstellen.

Hinweis:

Sind sowohl __unserialize() als auch __wakeup() im selben Objekt definiert, wird nur __unserialize() aufgerufen. __wakeup() wird ignoriert.

Hinweis:

Dieses Feature ist seit PHP 7.4.0 verfügbar.

Beispiel #2 Serialize und unserialize

<?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 
__serialize(): array
    {
        return [
          
'dsn' => $this->dsn,
          
'user' => $this->username,
          
'pass' => $this->password,
        ];
    }

    public function 
__unserialize(array $data): void
    
{
        
$this->dsn $data['dsn'];
        
$this->username $data['user'];
        
$this->password $data['pass'];

        
$this->connect();
    }
}
?>

__toString()

public __toString(): 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.

Warnung

Seit PHP 8.0.0 unterliegt der Rückgabewert dieser Methode der üblichen PHP Typsemantik. Das heißt, er wird wenn möglich in einen String umgewandelt, wenn strikte Typisierung deaktiviert ist.

Seit PHP 8.0.0 implementiert jede Klasse die eine __toString()-Methode enthält implizit auch das Interface Stringable und erfüllen daher auch Typprüfungen auf dieses Interface. Es wird dennoch empfohlen, dieses Interface explizit zu implementieren.

In PHP 7.4 muss der Rückgabewert ein String sein, andernfalls wird ein Error geworfen.

Vor PHP 7.4.0 muss der Rückgabewert ein String sein, ansonsten wird ein Fehler der Stufe E_RECOVERABLE_ERROR hervorgerufen.

Warnung

Es war vor PHP 7.4.0 nicht möglich eine Exception aus einer __toString()-Methode zu werfen. Dies resultierte in einem fatalen Fehler.

Beispiel #3 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

__invoke()

__invoke( $... = ?): mixed

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

Beispiel #4 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 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 #5 Verwendung von __set_state()

<?php
class A
{
    public 
$var1;
    public 
$var2;
    public static function 
__set_state($an_array)
    {
        
$obj = new A;
        
$obj->var1 $an_array['var1'];
        
$obj->var2 $an_array['var2'];
        return 
$obj;
    }
}
$a = new A;
$a->var1 5;
$a->var2 'foo';
$b var_export($atrue);
var_dump($b);
eval(
'$c = ' $b ';');
var_dump($c);
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

string(60) "A::__set_state(array(
   'var1' => 5,
   'var2' => 'foo',
))"
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, sodass der erneute Import von Objekten zu einer Error-Exception führt, falls __set_state() nicht implementiert ist. Die betrifft im Besonderen einige interne Klassen. Es liegt im Aufgabenbereich des Programmiers sicherzustellen, dass nur Objekte wieder re-importiert werden, welche auch __set_state() implementieren.

__debugInfo()

__debugInfo(): 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.

Beispiel #6 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)
}

Hier Kannst Du einen Kommentar verfassen


Bitte gib mindestens 10 Zeichen ein.
Wird geladen... Bitte warte.
* Pflichtangabe
Es sind noch keine Kommentare vorhanden.

Neuigkeiten für PHP-Entwickler: Laravel 11 Veröffentlichung

Am 12. März 2024 wurde die lang erwartete Version 11 des Laravel-Frameworks veröffentlicht, die eine Reihe von spannenden Neuerungen und Verbesserungen für die PHP-Entwicklungsgemeinschaft mit sich bringt. ...

Mike94

Autor : Mike94
Kategorie: PHP Magazin

Technisches SEO bleibt relevant

Technisches SEO – Was ist das überhaupt? Technisches SEO bezieht sich auf die Optimierung der technischen Aspekte deiner Webseite. Das Ziel ist klar! ...

admin

Autor : admin
Kategorie: SEO & Online-Marketing

Was ist neu in der PHP 8.2.10

PHP 8.2.10 ist eine der neuesten Versionen von PHP, die eine Reihe von Verbesserungen und neuen Funktionen mit sich bringt. In diesem Artikel werden wir einige der herausragenden Neuerungen und Verbesserungen dieser Version diskutieren. ...

admin

Autor : admin
Kategorie: Software-Updates

Tutorial veröffentlichen

Tutorial veröffentlichen

Teile Dein Wissen mit anderen Entwicklern weltweit

Du bist Profi in deinem Bereich und möchtest dein Wissen teilen, dann melde dich jetzt an und teile es mit unserer PHP-Community

mehr erfahren

Tutorial veröffentlichen

Seltsames Verhalten von execute() oder Fehler meinerseits

Hallo liebe Community, ich habe ein kleines Problem und vielleicht kann mir ja jemand helfen, würde ich mich sehr drüber freuen. Unten steht e ...

Geschrieben von garibaldiwz am 22.03.2024 13:03:12
Forum: SQL / Datenbanken
Google reCAPTCHA in Kontaktformular einbinden

Überprüfen Sie den E-Mail-Versand: Stellen Sie sicher, dass die E-Mail-Funktion mail() ordnungsgemäß funktioniert und dass keine Fehler beim V ...

Geschrieben von Gast am 18.03.2024 04:54:16
Forum: PHP Developer Forum
`count.php`

Hallo cober93327, und Danke fuer deine Antwort! :-) Naja, so einen "Besucherzähler" auf der Webseite anzuzeigen ist schon eher etwas, das man a ...

Geschrieben von kekse1 am 17.03.2024 15:56:38
Forum: Projekthilfe
`count.php`

Es gibt dazu natuerlich auch eine recht ausfuehrliche Dokumentation in meinem GitHub-Repository Es würde meiner Ansicht nach enorm helfen, wenn D ...

Geschrieben von cober93327 am 14.03.2024 15:49:28
Forum: Projekthilfe