Pourquoi ne peut-on pas attribuer les appels de fonction par défaut en PHP ?

Susan Sarandon
Libérer: 2024-10-17 20:34:02
original
293 Les gens l'ont consulté

Why Can't Attribute Defaults Function Calls in PHP?

Impossible d'appeler des fonctions dans les valeurs par défaut des attributs PHP

[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 :

<code class="php">class Foo {
    public $path = array(
        realpath(".")
    );
}</code>
Copier après la connexion

renvoie une erreur de syntaxe. Cependant, ce qui suit fonctionne de manière transparente :

<code class="php">$path = array(
    realpath(".")
);</code>
Copier après la connexion

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 ?

[Réponse]

Le code du compilateur PHP indique que cette restriction est intentionnelle, bien qu'aucune justification officielle ne soit disponible. L'implémentation de cette fonctionnalité de manière fiable 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 //...
;
Copier après la connexion

Par conséquent, pour attribuer des valeurs de variable telles que $ chemin, 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 ')' // ...
      //...
;
Copier après la connexion

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 ')' // ...
;
Copier après la connexion

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
Copier après la connexion

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
Copier après la connexion

Pour prendre en charge les appels de fonction dans les valeurs par défaut des attributs, un nouveau tableau d'opcodes étendu à 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.

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!

source:php
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!