[Übersetzung] [Entwicklung und Einbettung von PHP-Erweiterungen] Kapitel 11 – PHP5-Objekte
黄舟
Freigeben: 2023-03-05 16:26:01
Original
1523 Leute haben es durchsucht
Okay, aber die von PHP5-Objekten verwendeten API-Funktionen basieren immer noch auf der API von PHP4. Wenn Sie Kapitel 10 „php4-Objekte“ gelesen haben, sind Sie mit dem Inhalt dieses Kapitels einigermaßen vertraut Kapitel, Sie können wie in Kapitel 10 die Erweiterung in „sample3“ umbenennen und den redundanten Code bereinigen, sodass nur der Skelettcode der Erweiterung übrig bleibt. Die erste ist eine numerische Kennung, die der in Kapitel 9 „Ressourcendatentyp“ eingeführten numerischen Ressourcen-ID sehr ähnlich ist und eine Rolle spielt Die Rolle des Schlüssels zum Suchen von Objektinstanzen in der entsprechenden Tabelle Die Elemente in dieser Instanztabelle enthalten Verweise auf zend_class_entry und die interne Attributtabelle.
Das zweite Element ist die Objektvariable. Eine Handle-Tabelle, mit der Sie anpassen können, wie die Zend Engine Instanzen behandelt später in diesem Kapitel.
zend_class_entry
Ein Klasseneintrag ist eine interne Darstellung einer Klasse, die Sie im Benutzer definieren Wie Sie im vorherigen Kapitel gesehen haben, wird diese Struktur durch den Aufruf von INIT_CLASS_ENTRY() mit dem Klassennamen und seiner Funktionstabelle initialisiert. Als nächstes denken Sie vielleicht: „Es sieht aus.“ Bisher ziemlich gleich? Das PHP_METHOD()-Makro wurde in Zend Engine 2 eingeführt, das eine Kapselung des PHP_FUNCTION()-Makros ist und im Gegensatz zu PHP4 den Klassennamen und den Methodennamen kombiniert. Definieren Sie den Methodennamen manuell in der Erweiterung. Die Namespace-Auflösungsspezifikationen Ihres Codes in der Erweiterung stimmen mit denen anderer Betreuer
Definition
Define überein Um eine Methode zu implementieren, verbinden Sie sie einfach mit der Funktionstabelle der Klasse. Zusätzlich zum PHP_METHOD()-Makro, das für die Implementierung verwendet wird, gibt es einige neue Makros, die bei der Definition von Funktionslisten verwendet werden können.
Verglichen mit PHP_FE ()-Makro, das in Kapitel 5 „Ihre erste Erweiterung“ eingeführt wurde. PHP_ME() fügt am Ende einen Klassennamen-Parameter und einen Flags-Parameter hinzu (für bietet Zugriffskontrolle wie öffentliche, geschützte, private, statische sowie abstrakte und andere Optionen). . Um beispielsweise die helloWorld-Methode zu definieren, können Sie sie wie folgt definieren:
ist dem Makro PHP_FALIAS() sehr ähnlich. Mit diesem Makro können Sie die Methode für den Alias-Parameter beschreiben. Die Implementierung (innerhalb derselben Klasse) bietet a Um beispielsweise Ihre helloWorld-Methode zu kopieren, können Sie sie wie folgt definieren:
Da beispielsweise die zuvor definierte Methode Sample3_SecondClass::helloWorld() keine Objektinstanz erfordert, können Sie ihre Definition von „einfach“ ändern Ändern Sie ZEND_ACC_PUBLIC in ZEND_ACC_PUBLIC |, damit die Engine keine (Instanz) bereitstellt, nachdem sie es erkannt hat.
Magische Methode
Zusätzlich zu den magischen Methoden von ZE1 hat ZE2 viele neue magische Methoden hinzugefügt, wie in der folgenden Tabelle gezeigt (oder unter http://www.php.cn/ zu finden)
Methode
Verwendung
__construct(...)
Optionaler automatisch aufgerufener Objektkonstruktor ( zuvor eine Methode definiert, die mit dem Klassennamen übereinstimmt).if Beide Implementierungen von __construct() und classname() existieren , in instanziierter Form Während des Prozesses wird , dem Aufruf von __construct()
< Priorität einräumen 🎜>
__destruct()
Wenn die Instanz den Bereich verlässt, oder eine vollständige Beendigung anfordert , führt alle dazu, dass die Methode __destruct() der Instanz implizit aufgerufen wird, um einige Aufräumarbeiten durchzuführen,Zum Beispiel das Schließen einer Datei oder eines Netzwerk-Handles .
__clone()
Standardmäßig ,Alle Instanzen sind echte Pass-by-Reference.In php5, Um eine Objektinstanz tatsächlich zu kopieren,, müssen Sie das KlonenSchlüsselwort verwenden.Wenn Sie das Schlüsselwort Klonen für eine Objektinstanz aufrufen,
Die Methode __clone() wird implizit ausgeführt, wodurch das Objekt einige erforderliche interne Ressourcendaten kopieren kann.
__toString()
Bei Verwendung von Text zur Darstellung eines Objekts ,Zum Beispiel, wenn die Anweisung echo oder print direkt auf dem Objekt verwendet wird,
Die Methode __toString() wird automatisch von der Engine aufgerufen. Wenn die Klasse diese magische Methode implementiert, sollte eine Zeichenfolge mit einer Beschreibung des aktuellen Status des Objekts zurückgeben .
__get($var)
Wenn das Skript eine unsichtbare Eigenschaft eines Objekts anfordert ( nicht existiert oder aufgrund der Zugriffskontrolle unsichtbar ist )wenn,
__get()magische Methode wird aufgerufen,Der einzige Parameter ist der angeforderte Eigenschaftsname.Implementierung Sie kann seine eigene interne Logik verwenden, um den sinnvollsten Rückgabewert für zu ermitteln.
__set($var , $value)
und __get() sind sehr ähnlich,
__set() bietet die gegenteilige Fähigkeit , , die verwendet wird, um die Logik der Zuweisung zu unsichtbaren Eigenschaften eines Objekts zu handhaben __set() kann sich dafür entscheiden, diese Variablen implizit in Standardattributtabellen , zu erstellen und Werte mithilfe anderer Speichermechanismen festzulegen , Oder geben Sie einfach einen Fehler aus und verwerfen Sie den Wert .
__call($fname, $args)
Beim Aufrufen undefinierter Methoden eines Objekts können Sie mit __call()< schöne Ergebnisse erzielen 🎜>Magische Methode Die Verarbeitung von .Diese Methode akzeptiert zwei Parameter :Der aufgerufene Methodenname,Ein Array, das die numerischen Indizes aller im Aufruf übergebenen Argumente enthält.
__isset ($varname )
php5.1.0Nach ist der Aufruf von isset($obj->prop) nicht nur eine Überprüfung< Ob es prop in 🎜>$obj gibt, , wird auch aufgerufen $obj__isset()Methode, dynamische Auswertung versuchen, dynamisches Ob zu verwenden Mit den Methoden __get() und __set() können Attribute
<🎜 erfolgreich gelesen und geschrieben werden >
__unset($varname)
Ähnlich wie
__isset(), PHP 5.1 .0 führt eine einfache OOPSchnittstelle für die Funktion unset() ein. Es kann für Objekteigenschaften verwendet werden,Obwohl diese Eigenschaft möglicherweise nicht in der Standardeigenschaftentabelle des Objekts vorhanden ist,Aber es könnte für den dynamischen Eigenschaftsbereich von __get() und __set() sinnvoll sein, Daher wird __unset() eingeführt, um dieses Problem zu lösen.
get_property_ptr_ptr() ist eine Variante von read_property(), die es dem aufrufenden Bereich ermöglicht, den aktuellen zval * direkt durch einen neuen zu ersetzen. Das Standardverhalten besteht darin, die Standard-Eigenschaftstabelle zurückzugeben Die Zeigeradresse des Attributs in . Wenn es nicht vorhanden ist und keine magische Methode __get()/__set() vorhanden ist, wird der Zeiger implizit erstellt und zurückgegeben. Wenn die Methode __get() oder __set() vorhanden ist, wird dies der Fall sein Dies führt dazu, dass dieses Handle fehlschlägt, sodass die Engine stattdessen auf separate Aufrufe von read_property und write_property angewiesen ist Typ TSRMLS_DC)
read_dimension() und write_dimension() ähneln den entsprechenden read_property() und write_property(); sie werden jedoch ausgelöst, wenn auf das Objekt als Array mit der Methode $obj['idx'] zugegriffen wird Die Klasse des Objekts implementiert die ArrayAccess-Schnittstelle nicht. Das Standardverhalten besteht darin, einen Fehler auszulösen. Andernfalls werden die magischen Methoden offsetget($idx) oder offsetset($idx, $value) aufgerufen.
zval *get( zval *obj TSRMLS_DC)
void set(zval *obj, zval *value TSRMLS_DC)
Beim Festlegen oder Abrufen des Werts eines Objekts wird die Methode get() oder set() für das Objekt aufgerufen. Das Objekt selbst wird als erster Parameter übergeben . Für set wird der neue Wert als zweiter Parameter übergeben. Es gibt keinen Standardhandler für diese Operationen 🎜>int has_property(zval *obj, zval *prop, int chk_type TSRMLS_DC)
Dieser Handler wird aufgerufen, wenn isset() für eine Objekteigenschaft aufgerufen wird. Standardmäßig überprüft der Standardhandler den durch die Requisite angegebenen Attributnamen. Wenn dieses Attribut in PHP 5.1.0 nicht gefunden wird und die Methode __isset() definiert ist, wird diese Methode nur aufgerufen Attribut muss vorhanden sein. Wenn der chk_type-Wert 0 ist, muss er vorhanden sein und darf kein Wert von IS_NULL sein. Wenn der chk_type-Wert 1 ist, muss das Attribut vorhanden sein und einen anderen Wert als FALSE haben. X,
Die Bedeutung von chk_type stimmt mit dem chk_type von has_dimension überein.
int has_dimension(zval *obj, zval *idx, int chk_type TSRMLS_DC)
Beim Aufruf von isset() bei der Behandlung eines Objekts als Array (z. B. isset($obj['idx'])) wird dieser Prozessor verwendet Überprüfen Sie, ob das Objekt implementiert ist. Wenn die ArrayAccess-Schnittstelle implementiert ist, wird die Methode offsetexists($idx) aufgerufen. Wenn sie nicht gefunden wird (bezogen auf den Aufruf von offsetexists()), ist dies dasselbe, als ob die Methode offsetexists() nicht implementiert wäre. und 0 wird zurückgegeben, wenn chk_type 0 ist, direkt true(1) zurückgeben. Ein chk_type von 1 gibt an, dass die Methode offsetget($idx) des Objekts aufgerufen und der Rückgabewert getestet werden muss.
Geben Sie TRUE(1) nur zurück, wenn der Prüfwert nicht FALSE ist.
Diese beiden Methoden beim Entladen Objekteigenschaften (oder beim Anwenden von unset() auf ein Objekt in einem Array). Der Handler unset_property() entfernt entweder die Eigenschaft aus der Standardeigenschaftentabelle (falls vorhanden) oder versucht, die implementierte Methode __unset($prop) aufzurufen ( php 5.1.0), unset_dimension() ruft die Methode offsetunset($idx) auf, wenn die Klasse ArrayAccess implementiert.
HashTable *get_properties(zval *obj TSRMLS_DC)
Dieser Handler wird tatsächlich aufgerufen, wenn die interne Funktion das Z_OBJPROP()-Makro verwendet, um eine Eigenschaft aus der Standard-Eigenschaftstabelle zu lesen. Standardmäßige Verarbeitung von PHP-Objekten Der Prozessor entpackt und gibt Z_OBJ_P(object)->properties zurück, was eine echte Standard-Eigenschaftentabelle ist.
union _zend_function *get_method(zval **obj_ptr char *method_name , int methodname_len TSRMLS_DC)
Dieser Handler wird aufgerufen, wenn eine Objektmethode in der Funktionstabelle der Klasse analysiert wird. Wenn die Methode nicht in der Hauptfunktionstabelle vorhanden ist, gibt der Standardhandler einen Zeiger auf das Objekt _call($) zurück name, $args) Methode umschlossen zend_function * Zeiger.
int call_method(char *method, INTERNAL_FUNCTION_PARAMETERS)
Funktion, die als Typ ZEND_OVERLOADED_FUNCTION definiert ist, wird als call_method-Prozessor ausgeführt. Standardmäßig ist dieser Prozessor undefiniert.
union _zend_function *get_constructor(zval *obj TSRMLS_DC)
Ähnlich wie der get_method()-Prozessor gibt dieser Prozessor eine entsprechende Objektmethodenreferenz zurück. Der Konstruktor ist im zend_class_entry der Klasse gespeichert eine besondere Art und Weise, die sie zu etwas Besonderem macht.
Ähnlich wie get_constructor() wird dieser Prozessor selten überschrieben. Sein Zweck besteht darin, eine Objektinstanz zuzuordnen. Zurück zur ursprünglichen Klassendefinition.
int get_class_name(zval *object, char **name zend_uint *len, int parent TSRMLS_DC)
get_class_entry() ist ein Schritt von get_class_name(). Nach dem Abrufen des zend_object des Objekts wird der Klassenname des Objekts oder sein übergeordneter Klassenname (dies hängt vom Wert des Parameters parent ab) erstellt und die zurückgegebene Kopie des Klassennamens zurückgegeben Verwenden Sie nicht persistenten Speicher (emalloc()).
int Compare_objects(zval *obj1, zval * obj2 TSRMLS_DC)
Wenn Vergleichsoperatoren (z. B. ==, !=, <=, <, >, >=) verwendet werden. Wenn zwei Objekte vorhanden sind, wird der Aufruf von Compare_objects() auf dem Operanden (die beiden am Vergleich beteiligten Objekte) sind der erste Teil dieser Arbeit. Ihr Rückgabewert ist normalerweise 1, 0, -1, was jeweils „größer als“, „gleich“ und „kleiner als“ darstellt auf ihren Standardattributtabellen, wobei dieselben Vergleichsregeln wie die Array-Vergleichsregeln verwendet werden, die in Kapitel 8, „Arbeiten mit Arrays und HashTables“, gelernt wurden.
int cast_object( zval *src, zval *dst, int type, int Should_free TSRMLS_DC)
Beim Versuch, das Objekt in einen anderen Datentyp umzuwandeln, wird dieser Prozessor ausgelöst. Wenn Should_free auf einen Wert ungleich Null gesetzt ist, wird zval_dtor() auf dst aufgerufen und gibt zunächst die internen Ressourcen frei. Kurz gesagt, der Prozessor sollte versuchen, das Objekt in src als dst vom Typ zval * darzustellen. Dieser Handler ist standardmäßig nicht definiert, aber wenn er vorhanden ist, sollte er ERFOLGREICH oder FEHLER zurückgeben.
int count_elements (zval *obj, long *count TSRMLS_DC)
Objekte, die den Array-Zugriff implementieren, sollten diesen Handler definieren, der die aktuelle Anzahl der Elemente in „count“ setzt und ERFOLGREICH zurückgibt, wenn die aktuelle Instanz kein Array implementiert Zugriff, es sollte FAILURE zurückgeben, damit die Engine zurückgeht und die Standardattributtabelle überprüft.
Anmerkung: Die obige Handle-Tabelle und das von PHP-5.4.9 verwendete Der Übersetzer ist nicht mehr vollständig konsistent. Beim Studium dieses Teils können sich die Leser auf die Standard-Prozessor-Handle-Tabelle am Ende von Zend/zend_object_handlers.c beziehen.
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn