Dieser Artikel stellt hauptsächlich den PHP-Quellcode 27 vor: Die Identifizierung von PHP-Konstruktionsmethoden hat einen gewissen Referenzwert. Jetzt können Freunde in Not darauf verweisen.
Apropos PHP-Quelle Code siebenundzwanzig: PHPs Identifizierung von Konstruktormethoden
Wie wir alle wissen, verwendete PHP aus historischen Gründen früher den Klassennamen als Konstruktor, und der neue Konstruktor __construct wurde in PHP5 eingeführt. Wenn PHP 5 aus Gründen der Abwärtskompatibilität keine __construct()-Funktion in einer Klasse finden kann, versucht es, einen Konstruktor im alten Stil zu finden, bei dem es sich um eine Funktion mit demselben Namen wie die Klasse handelt. Daher treten Kompatibilitätsprobleme nur dann auf, wenn die Klasse bereits über eine Methode namens __construct() verfügt, diese jedoch kein Konstruktor ist.
Es gibt den folgenden Codeabschnitt
<?php class Foo { public function Foo() { } private function __construct() { } } new Foo(); die();
Zu diesem Zeitpunkt lautet die Ausgabe:
Schwerwiegender Fehler: Aufruf von privatem Foo::__construct() aus ungültigem Kontext
Zu diesem Zeitpunkt ist der von PHP erkannte Konstruktor __construct. Da er privat ist, tritt beim externen Aufruf ein Fehler auf.
Okay, lassen Sie uns den Grund anhand des C-Quellcodes von PHP herausfinden.
Suchen Sie zunächst direkt nach der Klassendefinition in der Erweiterungsklasse von spl:
spl_iterators.c 3228行 REGISTER_SPL_STD_CLASS_EX(IteratorIterator, spl_dual_it_new, spl_funcs_IteratorIterator);///spl_functions.h 31行#define REGISTER_SPL_STD_CLASS_EX(class_name, obj_ctor, funcs) \ spl_register_std_class(&spl_ce_ ## class_name, # class_name, obj_ctor, funcs TSRMLS_CC);//spl_functions.c 41行PHPAPI void spl_register_std_class(zend_class_entry ** ppce, char * class_name, void * obj_ctor, const zend_function_entry * function_list TSRMLS_DC) //spl_functions.c 2235行ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *orig_class_entry TSRMLS_DC) /* {{{ *///调用do_register_internal_class函数 //zend_API.c 2169行static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class_entry, zend_uint ce_flags TSRMLS_DC) /* {{{ *///调用zend_register_functions(class_entry, class_entry->builtin_functions, &class_entry->function_table, MODULE_PERSISTENT TSRMLS_CC); //zend_API.c 1795行/* Look for ctor, dtor, clone * If it's an old-style constructor, store it only if we don't have * a constructor already. */if ((fname_len == class_name_len) && !memcmp(lowercase_name, lc_class_name, class_name_len+1) && !ctor) { ctor = reg_function;} else if ((fname_len == sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME))) { ctor = reg_function;} scope->constructor = ctor;//在1961行 确认构造函数
Der obige Code ist Version PHP5.3.0
Aus dem obigen Tracking-Prozess, wenn das Programm alles registriert Funktionen: Wenn __construct (d. h. ZEND_CONSTRUCTOR_FUNC_NAME) vorhanden ist, wird der Konstruktor von class_name (Klassenname) überschrieben, sodass er als reguläre Mitgliedsfunktion existiert. Der Code lautet wie folgt:
<?php class Foo { public function Foo() { echo 'Foo'; } public function __construct() { echo '__construct'; }} $foo = new Foo(); $foo->Foo();
Für den im vorherigen Beispiel gemeldeten Fehler können wir
zend/zend_object_handlers.c Zeile 1057
ZEND_API Union _zend_function *zend_std_get_constructor(zval *object TSRMLS_DC )
Finden Sie die Quelle.
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, er wird für das Studium aller hilfreich sein. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website.
Verwandte Empfehlungen:
Eine kurze Diskussion des PHP-Quellcodes 25: Über die nächsten, aktuellen Schlüsselfunktionen
Das obige ist der detaillierte Inhalt vonEine kurze Diskussion zum PHP-Quellcode 27: PHPs Identifizierung von Konstruktionsmethoden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!