Comportement ambigu des appels de fonction en PHP : dévoiler la nuance cachée
En PHP, un comportement particulier apparaît lors de l'appel d'une fonction et de l'encapsulation de son résultat entre parenthèses. Cette action apparemment anodine peut altérer l'interprétation du résultat, conduisant potentiellement à un comportement inattendu.
Considérez l'extrait de code suivant :
error_reporting(E_ALL | E_STRICT); function get_array() { return array(); } function foo() { return reset(get_array()); // Error: "Only variables should be passed by reference" return reset((get_array())); // Success } foo();
Dans la première variante, tenter d'attribuer le résultat de get_array() à la fonction reset() déclenche une erreur, car il devrait s'agir d'une variable passée par référence. Cependant, lorsque nous mettons l'appel de fonction entre parenthèses, le script s'exécute avec succès.
Bien que l'on puisse spéculer sur la mécanique sous-jacente, un examen approfondi de la documentation ne parvient pas à fournir une explication explicite de ce phénomène.
En approfondissant les subtilités de la grammaire PHP et en utilisant des outils comme phc pour visualiser l'AST du code, nous avons révélé que les deux extraits aboutissent à des arbres d'analyse identiques. Cela élimine la possibilité d'altérations syntaxiques influençant le comportement.
Cependant, une inspection plus approfondie de la structure de l'opcode PHP révèle une mise en garde cachée dans l'opcode ZEND_SEND_VAR_NO_REF. Cet opcode dicte qu'une erreur de référence ne doit pas être générée lorsque l'argument n'est pas un appel de fonction et a un nombre de références de 1.
Dans la deuxième variante de foo(), l'appel de fonction n'est plus reconnu en raison aux parenthèses ajoutées. En conséquence, le système classe l'argument comme expr_without_variable et lance l'opcode SEND_VAR_NO_REF. Étant donné que le tableau renvoyé a un nombre de références de 1, il est considéré comme approprié en tant que variable, évitant ainsi l'erreur de référence.
Il est important de noter que ce comportement doit être considéré comme un bug et non comme une fonctionnalité intentionnelle. . S'appuyer sur de telles incohérences peut conduire à un code imprévisible et peu fiable.
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!