[Problème]
Malgré une expérience de programmation antérieure, un novice en PHP est perplexe face à une erreur d'attribut par défaut. Le code :
class Foo {
public $path = array(
realpath(".")
);
}
renvoie une erreur de syntaxe. Cependant, ce qui suit fonctionne de manière transparente :
$path = array(
realpath(".")
);
La question se pose : pourquoi les fonctions ne peuvent-elles pas être invoquées dans les valeurs par défaut des attributs ? Est-ce intentionnel ou s'agit-il d'un défaut d'implémentation ?
[Answer]
Le code du compilateur PHP indique que cette restriction est intentionnelle, bien qu'aucune justification officielle ne soit disponible. L'implémentation fiable de cette fonctionnalité pose certains défis, comme en témoignent les limitations de l'implémentation actuelle de PHP.
La grammaire du compilateur définit une déclaration de variable de classe comme :
class_variable_declaration: //... | T_VARIABLE '=' static_scalar //... ;
Par conséquent, pour attribuer des valeurs de variable telles que $path, la valeur attendue doit s'aligner sur un scalaire statique. Cela englobe les tableaux avec des valeurs qui sont également des scalaires statiques :
static_scalar: /* compile-time evaluated scalars */ //... | T_ARRAY '(' static_array_pair_list ')' // ... //... ;
Si la grammaire autorisait la syntaxe suivante, qui correspond à l'exemple de code, le script rencontrerait une erreur « Type de liaison non valide » :
class_variable_declaration: //... | T_VARIABLE '=' T_ARRAY '(' array_pair_list ')' // ... ;
L'analyse de l'exemple de code donné révèle les étapes suivantes :
zend_do_begin_class_declaration() // Adds an opcode array_init(), zend_do_add_static_array_element() // Do not create new opcodes, add array to class properties zend_do_declare_property() // Declares the property zend_do_early_binding() // Consumes the last opcode and evaluates it
Si l'opcode n'est pas attendu (par exemple, lié à des fonctions ou des méthodes), une erreur est générée.
Autoriser les tableaux non statiques génère un opcode INIT_ARRAY, qui perturbe zend_do_early_binding() :
DECLARE_CLASS 'Foo' SEND_VAL '.' DO_FCALL 'realpath' INIT_ARRAY
Pour prendre en charge les appels de fonction dans les valeurs par défaut des attributs, un nouveau tableau d'opcodes limité à la déclaration de variable de classe serait nécessaire, similaire aux définitions de méthodes. Cependant, déterminer le calendrier d'une telle évaluation présente des défis supplémentaires.
D'autres langages dynamiques ont réussi à résoudre ce problème, mais cela reste une fonctionnalité absente de PHP, potentiellement en raison de sa complexité et de sa faible priorité perçue.
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3