Quelle est la différence entre PHP print
et echo
?
Stack Overflow a de nombreuses questions sur l'utilisation de PHP print
et des echo
mots clés.
Le but de cet article est de fournir une question de référence canonique et une réponse sur PHP print
et les echo
mots-clés et de comparer leurs différences et leurs cas d'utilisation.
Réponses:
Pourquoi deux constructions?
La vérité à propos de l' impression et de l' écho est que, bien qu'ils apparaissent aux utilisateurs comme deux constructions distinctes, ils sont tous les deux vraiment des nuances d'écho si vous revenez à l'essentiel, c'est-à-dire regardez le code source interne. Ce code source implique l'analyseur ainsi que les gestionnaires d'opcode. Considérez une action simple telle que l'affichage du nombre zéro. Que vous utilisiez echo ou print, le même gestionnaire "ZEND_ECHO_SPEC_CONST_HANDLER" sera appelé. Le gestionnaire pour print fait une chose avant d'appeler le gestionnaire pour echo, il s'assure que la valeur de retour pour print est 1, comme suit:
(voir ici pour référence )
La valeur de retour est une commodité si l'on souhaite utiliser print dans une expression conditionnelle. Pourquoi 1 et pas 100? Eh bien, en PHP, la véracité de 1 ou 100 est la même, c'est-à-dire vraie, alors que 0 dans un contexte booléen équivaut à une valeur fausse. En PHP, toutes les valeurs non nulles (positives et négatives) sont des valeurs de vérité et cela dérive de l'héritage Perl de PHP.
Mais, si tel est le cas, alors on peut se demander pourquoi echo prend plusieurs arguments alors que print ne peut en gérer qu'un. Pour cette réponse, nous devons nous tourner vers l'analyseur, en particulier le fichier zend_language_parser.y . Vous noterez que l'écho a la flexibilité intégrée de sorte qu'il puisse imprimer une ou plusieurs expressions (voir ici ). tandis que print est contraint d'imprimer une seule expression (voir ici ).
Syntaxe
Dans le langage de programmation C et les langages influencés par celui-ci tels que PHP, il y a une distinction entre les instructions et les expressions. Syntaxiquement,
echo expr, expr, ... expr
est une instruction tandis queprint expr
est une expression puisqu'elle s'évalue à une valeur. Par conséquent, comme d'autres déclarations,echo expr
est autonome et est incapable d'inclure dans une expression:En revanche,,
print expr
peut à lui seul former une déclaration:Ou, faites partie d'une expression:
On pourrait être tenté de penser
print
que c'était un opérateur unaire, comme!
ou~
cependant ce n'est pas un opérateur. Ce qui!, ~ and print
a en commun, c'est qu'ils sont tous intégrés à PHP et chacun ne prend qu'un seul argument. Vous pouvez utiliserprint
pour créer le code étrange mais valide suivant:À première vue , le résultat peut sembler étrange que la dernière instruction d'impression imprime son opérande de « 7 » abord . Mais, si vous creusez plus profondément et regardez les opcodes réels, cela a du sens:
Le tout premier opcode généré est celui correspondant au 'print 7'. Le '~ 0' est une variable temporaire dont la valeur est 1. Cette variable devient un opérande pour le prochain opcode d'impression qui à son tour renvoie une variable temporaire et le processus se répète. La dernière variable temporaire n'est pas du tout utilisée, elle est donc libérée.
Pourquoi
print
renvoie- t-il une valeur etecho
non?Les expressions s'évaluent en valeurs. Par exemple,
2 + 3
évalue à5
etabs(-10)
évalue à10
. Puisqu'elleprint expr
est elle-même une expression, elle doit contenir une valeur et c'est le cas, une valeur cohérente de1
indique un résultat véridique et en renvoyant une valeur non nulle, l'expression devient utile pour être incluse dans une autre expression. Par exemple, dans cet extrait de code, la valeur de retour de print est utile pour déterminer une séquence de fonctions:Vous pouvez trouver l'impression d'une valeur particulière lorsqu'il s'agit de déboguer à la volée, comme l'illustre l'exemple suivant:
En remarque, en général, les déclarations ne sont pas des expressions; ils ne renvoient pas de valeur. L'exception, bien sûr, sont les instructions d'expression qui utilisent des expressions print et même des expressions simples utilisées comme instruction, comme
1;
une syntaxe dont PHP hérite de C. L'instruction d'expression peut sembler étrange mais elle est très utile, permettant de passer des arguments à les fonctions.Est-ce
print
une fonction?Non, c'est une construction de langage. Bien que tous les appels de fonction soient des expressions,
print (expr)
c'est une expression, malgré le visuel qui semble utiliser la syntaxe d'appel de fonction. En vérité, ces parenthèses sont une syntaxe parenthèses-expr, utile pour l'évaluation des expressions. Cela explique le fait qu'ils sont parfois facultatifs si l'expression est simple, commeprint "Hello, world!"
. Avec une expression plus complexe telle queprint (5 ** 2 + 6/2); // 28
les parenthèses, aide à l'évaluation de l'expression. Contrairement aux noms de fonction,print
est syntaxiquement un mot-clé et sémantiquement une «construction de langage» .Le terme «construction de langage» en PHP fait généralement référence à des «pseudo» fonctions comme
isset
ouempty
. Bien que ces "constructions" ressemblent exactement à des fonctions, ce sont en fait des fexprs , c'est-à-dire que les arguments leur sont passés sans être évalués, ce qui nécessite un traitement spécial de la part du compilateur.print
se trouve être une fexpr qui choisit d'évaluer son argument de la même manière qu'une fonction.La différence se voit en imprimant
get_defined_functions()
: aucuneprint
fonction n'est répertoriée. (Bienprintf
que les amis le soient: contrairementprint
, ce sont de vraies fonctions.)Pourquoi print (foo) fonctionne-t-il alors?
Pour la même raison qui
echo(foo)
fonctionne. Ces parenthèses sont très différentes des parenthèses d'appel de fonction car elles concernent plutôt des expressions. C'est pourquoi on peut coderecho ( 5 + 8 )
et s'attendre à ce qu'un résultat de 13 s'affiche (voir référence ). Ces parenthèses sont impliquées dans l'évaluation d'une expression plutôt que dans l'appel d'une fonction. Remarque: il existe d'autres utilisations des parenthèses en PHP, telles que les expressions if-conditionnelles, les listes d'affectations, les déclarations de fonctions, etc.Pourquoi
print(1,2,3)
etecho(1,2,3)
entraîner des erreurs de syntaxe?La syntaxe est
print expr
,echo expr
ouecho expr, expr, ..., expr
. Lorsque PHP rencontre(1,2,3)
, il essaie de l'analyser comme une seule expression et échoue, car contrairement à C, PHP n'a pas vraiment d'opérateur virgule binaire; la virgule sert plutôt de séparateur. (Vous pouvez néanmoins trouver une virgule binaire dans les boucles for de PHP, syntaxe héritée de C.)Sémantique
La déclaration
echo e1, e2, ..., eN;
peut être comprise comme du sucre syntaxique pourecho e1; echo e2; ...; echo eN;
.Étant donné que toutes les expressions sont des instructions et ont
echo e
toujours les mêmes effets secondaires queprint e
, et que la valeur de retour deprint e
est ignorée lorsqu'elle est utilisée comme une instruction, nous pouvons la comprendreecho e
comme du sucre syntaxique pourprint e
.Ces deux observations signifient que cela
echo e1, e2, ..., eN;
peut être considéré comme du sucre syntaxique pourprint e1; print e2; ... print eN;
. (Cependant, notez les différences d'exécution non sémantiques ci-dessous.)Il suffit donc de définir la sémantique pour
print
.print e
, une fois évalué:e
et convertit le type de la valeur résultante en une chaînes
. (Ainsi,print e
équivaut àprint (string) e
.)s
vers le tampon de sortie (qui sera éventuellement diffusé vers la sortie standard).1
.Différences au niveau du bytecode
print
implique une petite surcharge de remplissage de la variable de retour (pseudocode)single
echo
compile en un opcode:multi-valeur
echo
compile en plusieurs opcodesNotez que multi-valeur
echo
ne concatène pas ses arguments, mais les génère un par un.Référence:
zend_do_print
,zend_do_echo
.Différences d'exécution
ZEND_PRINT
est implémenté comme suit (pseudocode)Donc, il place essentiellement
1
la variable de résultat et délègue le travail réel auZEND_ECHO
gestionnaire.ZEND_ECHO
fait ce qui suitoù
zend_print_variable()
effectue la véritable "impression" (en fait, il ne fait que rediriger vers une fonction SAPI dédiée).Vitesse:
echo x
vsprint x
Contrairement à echo , print alloue une variable temporaire. Cependant, le temps consacré à cette activité est minime, donc la différence entre ces deux constructions linguistiques est négligeable.
Vitesse:
echo a,b,c
vsecho a.b.c
Le premier se compose de trois déclarations distinctes. Le second évalue l'expression entière
a.b.c.
, imprime le résultat et le supprime immédiatement. La concaténation impliquant des allocations de mémoire et des copies, la première option sera plus efficace.Alors lequel utiliser?
Dans les applications Web, la sortie est principalement concentrée dans les modèles. Étant donné que les modèles utilisent
<?=
, qui est l'alias deecho
, il semble logique de s'en tenir également àecho
d'autres parties du code.echo
présente un avantage supplémentaire de pouvoir imprimer plusieurs expressions sans les concaténer et n'implique pas une surcharge de remplissage d'une variable de retour temporaire. Alors, utilisezecho
.la source
echo $a,$b,$c
pour la concaténation de chaînes de caractères vars? Honnêtement, je n'ai jamais vu cela en cours d'utilisation.print
n'autorise qu'un seul argument,echo
peut en avoir plusieurs;echo
ne peut pas faire partie d'une expression tandis queprint
can et retourne ...; et peut-être un résumé des performances. Et toutes ces parties "pourquoi" et "sous le capot" aprèsJe sais que je suis en retard mais une chose que je voudrais ajouter est que dans mon code
donne une erreur "erreur de syntaxe, 'écho' inattendu (T_ECHO)"
tandis que
fonctionne très bien.
Docs about echo dit que "echo (contrairement à d'autres constructions de langage) ne se comporte pas comme une fonction" ici, mais à propos de print, docs dit aussi "print n'est pas réellement une fonction réelle (c'est une construction de langage)" ici . Alors je ne sais pas pourquoi. Et aussi à propos de l'écho et des documents d'impression, il est dit: "Les principales différences avec echo sont que print n'accepte qu'un seul argument et renvoie toujours 1." ici
Je serais heureux si quelqu'un pouvait faire la lumière sur ce comportement.
la source