91 votes

Quelle est la différence entre une structure du langage, et un "built-in" de la fonction en PHP?

Je sais qu' include, isset, require, print, echo, et certains autres ne sont pas des fonctions mais des constructions d'un langage.

Certaines de ces constructions d'un langage de besoin de parenthèses, d'autres ne le font pas.

require 'file.php';
isset($x);

Certains ont une valeur de retour, d'autres ne le font pas.

print 'foo'; //1
echo  'foo'; //no return value

Quel est donc l' interne différence entre une construction du langage et une fonction intégrée?

129voto

Tim Points 33042

(C'est plus long que j'ai voulu; s'il vous plaît garder avec moi.)

La plupart des langues sont constitués de quelque chose qui s'appelle une "syntaxe": le langage est composé de plusieurs mots-clés définis, et la gamme complète des expressions que vous pouvez construire dans cette langue est construite à partir de cette syntaxe.

Par exemple, disons que vous avez un simple quatre-fonction arithmétique "langue" qui ne prend qu'un seul chiffre les nombres entiers en entrée et ignore complètement l'ordre des opérations (je vous ai dit que c'était un langage simple). Cette langue pourrait être défini par la syntaxe suivante:

// The | means "or" and the := represents definition
$expression := $number | $expression $operator $expression
$number := 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
$operator := + | - | * | /

À partir de ces trois règles, vous pouvez construire n'importe quel nombre d'un seul chiffre-saisie des expressions arithmétiques. Vous pouvez ensuite écrire un analyseur syntaxique pour cette syntaxe qui décompose tout d'entrée valide dans sa composante types ($expression, $numberou $operator) et traite le résultat. Par exemple, l'expression 3 + 4 * 5 peut être décomposé comme suit:

// Parentheses used for ease of explanation; they have no true syntactical meaning
$expression = 3 + 4 * 5
            = $expression $operator (4 * 5) // Expand into $exp $op $exp
            = $number $operator $expression // Rewrite: $exp -> $num
            = $number $operator $expression $operator $expression // Expand again
            = $number $operator $number $operator $number // Rewrite again

Maintenant, nous avons une entièrement analysée de la syntaxe, dans notre langue, de l'expression d'origine. Une fois que nous avons cela, nous pouvons passer et d'écrire un analyseur de retrouver les résultats de toutes les combinaisons de $number $operator $number, et cracher un résultat quand nous n'avons qu'un $number à gauche.

Prendre note qu'il n'existe pas $expression des constructions de gauche dans la dernière version analysée de notre expression originale. C'est parce qu' $expression peut toujours être réduit à une combinaison d'autres choses dans notre langue.

PHP est un peu la même: les constructions de langage sont reconnus comme l'équivalent de notre - $number ou $operator. Ils ne peuvent être réduits dans d'autres constructions de langage; au lieu de cela, ils sont les unités de base à partir de laquelle la langue est construit. La principale différence entre les fonctions et les constructions de langage, c'est que l'analyseur traite directement avec les constructions de langage. Il simplifie les fonctions dans les constructions de langage.

La raison que les constructions de langage peut ou ne peut pas exiger des parenthèses et la raison pour laquelle certains ont des valeurs de retour tandis que d'autres ne dépend entièrement sur les détails techniques de l'analyseur PHP, la mise en œuvre. Je ne suis pas bien versé dans la façon dont l'analyseur fonctionne, donc je ne peux pas répondre à ces questions, mais imaginez une seconde une langue qui commence par:

$expression := ($expression) | ...

Effectivement, cette langue est libre de prendre toutes les expressions qu'il trouve et de se débarrasser de l'entourage des parenthèses. PHP (et ici, je suis employant pure conjecture) peuvent avoir recours à quelque chose de similaire pour ses constructions de langage: print("Hello") pourrait se réduit vers le bas pour print "Hello" avant d'être analysée, ou vice-versa (la définition de la langue peut ajouter entre parenthèses, ainsi que de se débarrasser d'eux).

C'est la racine de pourquoi vous ne pouvez pas redéfinir les constructions de langage comme echo ou print: ils sont effectivement codé en dur dans l'analyseur, alors que les fonctions sont associées à un ensemble de constructions d'un langage et de l'analyseur vous permet de la modifier de la cartographie à la compilation ou à l'exécution pour le remplacer par votre propre ensemble de constructions de langage ou des expressions.

À la fin de la journée, la différence entre les constructions et les expressions est ceci: les constructions de langage sont compris et pris en considération par l'analyseur. Les fonctions intégrées, tandis que fournis par le langage, sont cartographiés et simplifié à un ensemble de constructions de langage avant l'analyse.

Plus d'infos:

  • Backus-Naur form, la syntaxe utilisée pour définir des langages formels (yacc utilise ce formulaire)

Edit: lu quelques-uns des autres réponses, les gens font des bons points. Parmi eux:

  • Une langue builtin est plus rapide à l'appel à une fonction. C'est vrai, si seulement légèrement, parce que le PHP n'a pas besoin de carte que la fonction du langage-builtin équivalents avant l'analyse. Sur une machine moderne, cependant, la différence est assez négligeable.
  • Une langue builtin contourne la vérification des erreurs. Cela peut ou peut ne pas être vrai, selon le PHP internes de mise en œuvre pour chaque builtin. Il est certainement vrai que, le plus souvent, les fonctions sont plus avancé de vérification des erreurs et d'autres fonctionnalités que les builtins ne le font pas.
  • Les constructions de langage ne peut pas être utilisé en tant que fonction de rappels. C'est vrai, car une construction n'est pas une fonction. Ils sont des entités distinctes. Lorsque l'on code un builtin, vous n'êtes pas coder une fonction qui prend comme arguments - la syntaxe de la fonction est gérée directement par l'analyseur, et est reconnu comme un builtin, plutôt qu'une fonction. (Cela peut être plus facile à comprendre si vous envisagez de langues avec la première classe de fonctions: effectivement, vous pouvez passer des fonctions autour des objets. Vous ne pouvez pas le faire avec les builtins.)

15voto

Pascal MARTIN Points 195780

Les constructions de langage sont fournis par le langage lui-même (comme les instructions comme "si", "tout", ...), d'où leur nom.

Une conséquence de cela est qu'ils sont plus rapides à l'appel de fonctions (ou alors j'ai entendu/lu plusieurs fois)

Je ne sais pas comment c'est fait, mais une chose qu'ils peuvent faire (en raison d'être intégré directement dans le langage) est "bypass" une sorte de mécanisme de gestion des erreurs. Par exemple, la fonction isset peut être utilisé avec n'-variables existantes sans causer un Avis :

function test($param) {}
if (test($a)) {
    // Notice: Undefined variable: a
}

if (isset($b)) {
    // No notice
}

Remarque il n'est pas le cas pour toutes les langues des constructions.

Une autre différence entre les fonctions et les constructions de langage, c'est que certains de ceux-ci peuvent être appelés sans parenthèse, comme un mot clé.

Par exemple :

echo 'test'; // language construct => OK

function my_function($param) {}
my_function 'test'; // function => Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING

Ici aussi, il n'est pas le cas pour toutes les constructions de langage.

Je suppose qu'il n'y a absolument aucun moyen de "désactiver" une construction du langage : il fait partie de la langue elle-même. D'autre part, beaucoup de "builtin" les fonctions de PHP ne sont pas vraiment intégrés, et sont fournis par des extensions, qui, pour certains, sont toujours activé (mais pas tous)

Une autre différence est que les constructions de langage ne peuvent pas être utilisées comme des "pointeurs de fonction" (je veux dire, les rappels, par exemple) :

$a = array(10, 20);

function test($param) {echo $param . '<br />';}
array_map('test', $a);  // OK (function)

array_map('echo', $a);  // Warning: array_map() expects parameter 1 to be a valid callback, function 'echo' not found or invalid function name

Je n'ai pas d'autre idée de venir à mon esprit en ce moment... et je ne sais pas beaucoup sur le fonctionnement interne de PHP... Donc ça va être tout droit maintenant ^^

Si vous n'obtenez pas beaucoup de réponses ici, peut-être pourriez-vous vous demander ce à la mailling-liste des éléments internes (voir http://www.php.net/mailing-lists.php ), où il y a beaucoup de PHP de base-les développeurs ; ils sont ceux qui connaissent probablement de ce genre de choses ^^

(Et je suis vraiment intéressé par les autres réponses, d'ailleurs ^^ )

De référence : liste de mots clés et de constructions de langage en PHP

4voto

terminus Points 3966

Après patauger dans le code, j'ai trouvé que php traite de certains des instructions dans un fichier yacc. Ils sont donc des cas particuliers.

(voir Zend/zend_language_parser.y)

Hormis cela, je ne pense pas qu'il existe d'autres différences.

1voto

Jason S Points 58434

Vous pouvez remplacer les fonctions intégrées. Les mots clés sont toujours.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X