Cet article présente principalement le code source PHP vingt-sept : l'identification des méthodes de construction par PHP a une certaine valeur de référence. Maintenant, je le partage avec vous. Les amis dans le besoin peuvent s'y référer
En parlant de la source PHP. code vingt-sept : identification par PHP des méthodes de constructeur
Comme nous le savons tous, pour des raisons historiques, PHP utilisait le nom de classe comme constructeur, et le nouveau constructeur __construct a été introduit dans PHP5. Pour des raisons de compatibilité ascendante, si PHP 5 ne trouve pas de fonction __construct() dans une classe, il essaiera de trouver un constructeur à l'ancienne, qui est une fonction portant le même nom que la classe. Par conséquent, la seule situation où des problèmes de compatibilité surviendront est si la classe possède déjà une méthode nommée __construct(), mais qu’elle n’est pas un constructeur.
Il y a le morceau de code suivant
<?php class Foo { public function Foo() { } private function __construct() { } } new Foo(); die();
À ce moment, le résultat est :
Erreur fatale : appel au privé Foo::__construct() à partir d'un contexte invalide
Ceci À l'heure actuelle, le constructeur reconnu par PHP est __construct Parce qu'il est privé, une erreur se produit lors d'un appel externe.
D'accord, découvrons la raison à partir du code source C de PHP.
Commencez par regarder directement la définition de classe dans la classe d'extension de 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行 确认构造函数
Le code ci-dessus est pour la version php5.3.0
À partir du processus de suivi ci-dessus, le programme enregistre toutes les fonctions Lorsque __construct (c'est-à-dire ZEND_CONSTRUCTOR_FUNC_NAME) existe, le constructeur de class_name (nom de classe) sera écrasé afin qu'il existe en tant que fonction membre régulière. Le code est le suivant :
<?php class Foo { public function Foo() { echo 'Foo'; } public function __construct() { echo '__construct'; }} $foo = new Foo(); $foo->Foo();
Pour l'erreur rapportée dans l'exemple précédent, on peut
zend/zend_object_handlers.c ligne 1057
ZEND_API union _zend_function *zend_std_get_constructor(zval * objet TSRMLS_DC)
Trouver la source.
Ce qui précède représente l'intégralité du contenu de cet article. J'espère qu'il sera utile à l'étude de chacun. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois !
Recommandations associées :
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!