web-dev-qa-db-fra.com

Référence: comparaison de l'impression et de l'écho de PHP

Quelle est la différence entre PHP print et echo?

Stack Overflow a de nombreuses questions concernant l'utilisation des mots clés PHP print et echo.

Le but de cet article est de fournir une canonique référence question et réponse sur les mots clés PHP print et echo et de comparer leurs différences et leurs cas d'utilisation.

177
user187291

Pourquoi deux constructions?

La vérité sur print et echo est que même si elles apparaissent aux utilisateurs comme deux constructions distinctes, elles sont toutes les deux des nuances d'écho si vous passez aux bases, c'est à dire regarder le code source interne. Ce code source implique l'analyseur ainsi que les gestionnaires d'opcode. Envisagez une action simple telle que l'affichage du nombre zéro. Que vous utilisiez l'écho ou l'impression, le même gestionnaire "ZEND_ECHO_SPEC_CONST_HANDLER" sera invoqué. Le gestionnaire d'impression fait une chose avant d'appeler le gestionnaire d'écho, il s'assure que la valeur de retour pour l'impression est 1, comme suit:

ZVAL_LONG(&EX_T(opline->result.var).tmp_var, 1);

(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 non 100? Eh bien dans PHP la véracité de 1 ou 100 est la même, c'est-à-dire vrai, tandis que 0 dans un contexte booléen équivaut à une fausse valeur. Dans PHP tout non -les valeurs nulles (positives et négatives) sont des valeurs véridiques et cela découle de l'héritage Perl de PHP.

Mais, si c'est le cas, alors on peut se demander pourquoi echo prend plusieurs arguments alors que print ne peut en gérer qu'un seul. Pour cette réponse, nous devons nous tourner vers l'analyseur, en particulier le fichier zend_language_parser.y . Vous remarquerez que l'écho a la flexibilité intégrée afin qu'il puisse imprimer une ou plusieurs expressions (voir ici ). alors que print est contraint d'imprimer une seule expression (voir there ).

Syntaxe

Dans le langage de programmation C et les langages influencés par celui-ci comme PHP, il existe une distinction entre les instructions et les expressions. Syntaxiquement, echo expr, expr, ... expr Est une instruction tandis que print expr Est une expression car il évalue à une valeur. Par conséquent, comme d'autres instructions, echo expr Est autonome et ne peut pas être inclus dans une expression:

5 + echo 6;   // syntax error

En revanche, print expr, Peut à lui seul former une déclaration:

print 5; // valid

Ou, faites partie d'une expression:

   $x = (5 + print 5); // 5 
   var_dump( $x );     // 6 

On pourrait être tenté de penser à print comme s'il s'agissait d'un opérateur unaire, comme ! Ou ~ Mais ce n'est pas un opérateur. Ce que !, ~ 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 utiliser print pour créer le code bizarre mais valide suivant code:

    <?php 
    print print print print 7; // 7111

À première vue, le résultat peut sembler étrange que la dernière instruction print imprime son opérande '7' d'abord. Mais, si vous creusez plus profondément et regardez les opcodes réels, il est logique:

line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   3     0  >   PRINT                                            ~0      7
         1      PRINT                                            ~1      ~0
         2      PRINT                                            ~2      ~1
         3      PRINT                                            ~3      ~2
         4      FREE                                                     ~3
         5    > RETURN                                                   1

Le tout premier opcode généré est celui correspondant à 'print 7'. Le '~ 0' est une variable temporaire dont la valeur est 1. Cette variable devient et l'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 utilisée du tout, elle est donc libérée.

Pourquoi print renvoie une valeur et echo ne le fait pas?

Les expressions sont évaluées en valeurs. Par exemple, 2 + 3 Est évalué à 5 Et abs(-10) est évalué à 10. Puisque print expr Est lui-même une expression, alors il doit contenir une valeur et il le fait, une valeur cohérente de 1 Indique un résultat véridique et en renvoyant une valeur non nulle, l'expression devient utile pour l'inclusion dans une autre expression. Par exemple, dans cet extrait, la valeur de retour de print est utile pour déterminer une séquence de fonctions:

<?php

function bar( $baz ) { 
   // other code   
}
function foo() {
  return print("In and out ...\n");
}

if ( foo() ) {

     bar();
}

Vous pouvez trouver une impression d'une valeur particulière lorsqu'il s'agit de déboguer à la volée, comme l'illustre l'exemple suivant:

<?php
$haystack = 'abcde';
$needle = 'f';
strpos($haystack,$needle) !== FALSE OR print "$needle not in $haystack"; 

// output: f not in abcde

En tant que note secondaire, généralement, 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 imprimées et même simples utilisées comme instruction, comme 1;, Une syntaxe qui PHP hérite de C. L'instruction d'expression peut semble étrange mais il est très utile, ce qui permet de passer des arguments aux fonctions.

print est-elle une fonction?

Non, c'est une construction de langage. Alors que tous les appels de fonction sont des expressions, print (expr) est une expression, malgré le visuel qui semble utiliser la syntaxe d'appel de fonction. En vérité, ces parenthèses sont une syntaxe expr-parenthèses, utile pour l'évaluation des expressions. Cela explique le fait qu'ils sont parfois facultatifs si l'expression est simple, comme print "Hello, world!". Avec une expression plus complexe telle que print (5 ** 2 + 6/2); // 28 les parenthèses facilitent l'évaluation de l'expression. Contrairement aux noms de fonction, print est syntaxiquement un mot-clé , et sémantiquement un "construction de langage" .

Le terme "construction de langage" dans PHP fait généralement référence à des "pseudo" fonctions comme isset ou empty. Bien que ces "constructions" ressemblent exactement à des fonctions, elles sont en fait 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 un fexpr qui choisit d'évaluer son argument dans de la même manière qu'une fonction.

La différence peut être vue en imprimant get_defined_functions(): aucune fonction print n'est répertoriée. (Bien que printf et amis soient: contrairement à print, ce sont de vraies fonctions.)

Pourquoi l'impression (foo) fonctionne-t-elle alors?

Pour la même raison queecho(foo) fonctionne. Ces parenthèses sont très différentes des parenthèses d'appel de fonction car elles se rapportent plutôt aux expressions. C'est pourquoi on peut coder echo ( 5 + 8 ) et attendre un résultat de 13 à afficher (voir référence ). Ces parenthèses participent à l'évaluation d'une expression plutôt qu'à l'invocation d'une fonction. Remarque: il existe d'autres utilisations des parenthèses en PHP, telles que des expressions if-conditionnelles, des listes d'affectations, des déclarations de fonctions, etc.

Pourquoi print(1,2,3) et echo(1,2,3) entraînent-ils des erreurs de syntaxe?

La syntaxe est print expr, echo expr Ou echo 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 de opérateur virgule binaire; la virgule sert plus 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

L'instruction echo e1, e2, ..., eN; Peut être comprise comme du sucre syntaxique pour echo e1; echo e2; ...; echo eN;.

Étant donné que toutes les expressions sont des instructions et que echo e A toujours les mêmes effets secondaires que print e Et que la valeur de retour de print e Est ignorée lorsqu'elle est utilisée comme instruction, nous pouvons comprendre echo e Comme sucre syntaxique pour print e.

Ces deux observations signifient que echo e1, e2, ..., eN; Peut être considéré comme du sucre syntaxique pour print e1; print e2; ... print eN;. (Cependant, notez les différences d'exécution non sémantique ci-dessous.)

Il suffit donc de définir la sémantique de print. print e, Une fois évalué:

  1. évalue son seul argument e et type-cast la valeur résultante dans une chaîne s. (Ainsi, print e Est équivalent à print (string) e.)
  2. Diffuse la chaîne s vers le tampon de sortie (qui sera finalement diffusé sur la sortie standard).
  3. Évalue à l'entier 1.

Différences au niveau du bytecode

print implique une petite surcharge de remplissage de la variable de retour (pseudocode)

print 125;

PRINT  125,$temp     ; print 125 and place 1 in $temp 
UNSET  $temp         ; remove $temp

single echo compile en un seul opcode:

echo 125;

ECHO 125

multi-valeur echo compile en plusieurs opcodes

echo 123, 456;

ECHO 123
ECHO 456

Notez que la valeur multiple 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)

PRINT  var, result:

    result = 1
    ECHO var

Donc, il place essentiellement 1 Dans la variable de résultat et délègue le vrai travail au gestionnaire ZEND_ECHO. ZEND_ECHO fait ce qui suit

ECHO var:

    if var is object
        temp = var->toString()
        zend_print_variable(temp)
    else
        zend_print_variable(var)

zend_print_variable() exécute l '"impression" réelle (en fait, elle redirige simplement vers une fonction SAPI dédiée).

Vitesse: echo x Vs print x

Contrairement à echo , print alloue une variable temporaire. Cependant, le temps consacré à cette activité est minuscule, de sorte que la différence entre ces deux constructions linguistiques est négligeable.

Vitesse: echo a,b,c Vs echo a.b.c

Le premier compile en trois déclarations distinctes. Le second évalue l'expression entière a.b.c., Imprime le résultat et le supprime immédiatement. Étant donné que la concaténation implique des allocations de mémoire et la copie, la première option sera plus efficace.

Alors lequel utiliser?

Dans les applications Web, la sortie est principalement concentrée dans des modèles. Comme les modèles utilisent <?=, Qui est l'alias de echo, il semble logique de s'en tenir à echo dans d'autres parties du code. echo a l'avantage supplémentaire de pouvoir imprimer plusieurs expressions sans les concaténer et n'implique pas de surcharge de remplissage d'une variable de retour temporaire. Donc, utilisez echo.

181
user187291

Je sais que je suis en retard, mais je voudrais ajouter une chose: dans mon code

 $stmt = mysqli_stmt_init($connection) or echo "error at init"; 

donne une erreur "erreur de syntaxe, 'écho' inattendu (T_ECHO)"

tandis que

 $stmt = mysqli_stmt_init($connection) or print "error at init";

fonctionne bien.

Docs sur echo dit "echo (contrairement à d'autres constructions de langage) ne se comporte pas comme une fonction" ici mais sur print docs dit également "print n'est pas réellement une fonction réelle (c'est une construction de langage)" " ici . Je ne sais donc pas pourquoi. Et également à propos des documents echo et print, "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.

0
Mahad Ali