Christian Seiler: Lese ich das richtig? PHP-Objekte ähnlich flexibel wie in JS?

Beitrag lesen

Hallo Felix,

heute las ich auf heise.de über PHP5.3 und die darin enthaltenen neuen Features, darunter z.B. Closures und anonyme Funktionen usw. Bedeutet das, dass man in PHP5.3 ähnlich wie in JavaScript Objekte zur Laufzeit erweitern und verändern kann?

Jain. Um mal etwas aus der internen Perspektive zu erzählen (ich war an der Implementierung von Closures in PHP beteiligt): Es gab ziemlich viele Diskussionen auf der PHP-Mailingliste, wie man Closures dazu verwenden kann, um Objekte zu erweitern. Es wurde aber festgestellt, dass dies zu vielen Problemen führt, wenn man das mit anderen PHP-OOP-Semantiken verbindet (Visibility wie private/protected/public was es in JS so direkt nicht gibt sondern nur über Closures emuliert, andere Namensräume für Variablen und Methoden in Objekten, etc.). Die verschiedenen Ansätze, die es gab, hatte ich vor langer Zeit mal in http://wiki.php.net/rfc/closures/object-extension zusammengefasst. Nachdem auf der PHP-Mailingliste aber kein Konsens entstehen konnte, welchen Weg man wählen will, wurde entschieden, dass Closures gar keinen Zugriff auf $this haben, damit man das zu einem späteren Zeitpunkt noch nachrüsten kann (http://wiki.php.net/rfc/closures/removal-of-this).

Allerdings: Es gibt bestimmte Dinge, die Du bereits jetzt machen kannst:

Python-artige Variante mit $self als ersten Parameter:

class MeineKlasse {  
  public $begruessung = 'Hallo';  
  public function __call ($method, $args) {  
    array_unshift ($args, $this);  
    return call_user_func_array ($this->$method, $args);  
  }  
}  
  
$objekt = new MeineKlasse;  
$objekt->hallo = function ($self, $wer) {  
  echo $self->begruessung." ".$wer."!\n";  
};  
$objekt->hallo ('Welt');

Objekt als Closure-Variable:

class MeineKlasse {  
  public $begruessung = 'Hallo';  
  public function __call ($method, $args) {  
    return call_user_func_array ($this->$method, $args);  
  }  
}  
  
$objekt = new MeineKlasse;  
$objekt->hallo = function ($wer) use ($objekt) {  
  echo $objekt->begruessung." ".$wer."!\n";  
};  
$objekt->hallo ('Welt');

Allerdings: In den so erweiterten Methoden hast Du nur Zugriff auf die Variablen/Methoden des Objekts, die public sind. Auf private/protected kannst Du so nicht zugreifen. Aber Du kannst mit dieser Logik PHP-Objekte, deren Klasse es über __call zulässt selbst beliebig erweitern mit Closures - so ähnlich wie Javascript.

Viele Grüße,
Christian

--
Mein "Weblog" [RSS]
Using XSLT to create JSON output (Saxon-B 9.0 for Java)
»I don't believe you can call yourself a web developer until you've built an app that uses hyperlinks for deletion and have all your data deleted by a search bot.«
            -- Kommentar bei TDWTF