¿Cuál es la diferencia entre PHP printy echo?
Stack Overflow tiene muchas preguntas sobre PHP printy el echouso de palabras clave.
El propósito de esta publicación es proporcionar una pregunta y respuesta de referencia canónica sobre PHP printy echopalabras clave y comparar sus diferencias y casos de uso.

Respuestas:
¿Por qué dos construcciones?
La verdad acerca de la impresión y el eco es que, si bien los usuarios los ven como dos construcciones distintas, ambos son realmente sombras de eco si se llega a lo básico, es decir, mire el código fuente interno. Ese código fuente involucra tanto el analizador como los manejadores de código de operación. Considere una acción simple como mostrar el número cero. Ya sea que use echo o print, se invocará el mismo controlador "ZEND_ECHO_SPEC_CONST_HANDLER". El controlador para imprimir hace una cosa antes de invocar al controlador para echo, se asegura de que el valor de retorno para print sea 1, de la siguiente manera:
(ver aquí para referencia )
El valor de retorno es conveniente si se desea utilizar print en una expresión condicional. ¿Por qué 1 y no 100? Bueno, en PHP, la veracidad de 1 o 100 es la misma, es decir, verdadera, mientras que 0 en un contexto booleano equivale a un valor falso. En PHP, todos los valores distintos de cero (positivo y negativo) son valores verdaderos y esto se deriva del legado de Perl de PHP.
Pero, si este es el caso, entonces uno puede preguntarse por qué echo toma múltiples argumentos mientras que print solo puede manejar uno. Para esta respuesta, debemos recurrir al analizador, específicamente al archivo zend_language_parser.y . Notarás que echo tiene la flexibilidad incorporada para que pueda imprimir una o varias expresiones (ver aquí ). mientras que print se limita a imprimir solo una expresión (ver allí ).
Sintaxis
En el lenguaje de programación C y los lenguajes influenciados por él, como PHP, hay una distinción entre declaraciones y expresiones. Sintácticamente,
echo expr, expr, ... expres una declaración, mientras queprint expres una expresión, ya que se evalúa como un valor. Por lo tanto, como otras declaraciones, seecho exprsostiene por sí solo y es incapaz de ser incluido en una expresión:Por el contrario,
print exprsolo puede formar una declaración:O ser parte de una expresión:
Uno podría sentirse tentado a pensar
printque se trata de un operador unario, como!o~no es un operador. Lo que!, ~ and printtienen en común es que todos están integrados en PHP y cada uno toma solo un argumento. Puede usarprintpara crear el siguiente código extraño pero válido:A primera vista, el resultado puede parecer extraño que la última declaración de impresión imprima primero su operando de '7' . Pero, si profundiza y mira los códigos de operación reales, tiene sentido:
El primer código de operación que se genera es el correspondiente a la 'impresión 7'. El '~ 0' es una variable temporal cuyo valor es 1. Esa variable se convierte y operando para el siguiente código de operación de impresión que a su vez devuelve una variable temporal y el proceso se repite. La última variable temporal no se usa en absoluto, por lo que se libera.
¿Por qué
printdevuelve un valor yechono lo hace?Las expresiones evalúan los valores. Por ejemplo
2 + 3evalúa a5, yabs(-10)se evalúa como10. Dado queprint expres en sí misma una expresión, entonces debe contener un valor y lo hace, un valor consistente de1indica un resultado verdadero y al devolver un valor distinto de cero la expresión se vuelve útil para su inclusión en otra expresión. Por ejemplo, en este fragmento, el valor de retorno de print es útil para determinar una secuencia de funciones:Puede encontrar impresiones de un valor particular cuando se trata de depurar sobre la marcha, como lo ilustra el siguiente ejemplo:
Como nota al margen, en general, las declaraciones no son expresiones; No devuelven un valor. La excepción, por supuesto, son las declaraciones de expresión que usan expresiones impresas e incluso simples usadas como una declaración, como
1;una sintaxis que PHP hereda de C. La declaración de expresión puede parecer extraña pero es muy útil, ya que permite pasar argumentos a funcionesEs
printuna función?No, es una construcción de lenguaje. Si bien todas las llamadas a funciones son expresiones,
print (expr)es una expresión, a pesar de lo visual que aparece como si estuviera usando la sintaxis de llamadas a funciones. En verdad, estos paréntesis son sintaxis paréntesis-expr, útiles para la evaluación de expresiones. Eso explica el hecho de que a veces son opcionales si la expresión es simple, comoprint "Hello, world!". Con una expresión más compleja, comoprint (5 ** 2 + 6/2); // 28los paréntesis, ayuda a evaluar la expresión. A diferencia de los nombres de funciones,printes sintácticamente una palabra clave y semánticamente una "construcción de lenguaje" .El término "construcción de lenguaje" en PHP generalmente se refiere a funciones "pseudo" como
issetoempty. Aunque estas "construcciones" se ven exactamente como funciones, en realidad son fexprs , es decir, los argumentos se les pasan sin ser evaluados, lo que requiere un tratamiento especial del compilador.printresulta ser un fexpr que elige evaluar su argumento de la misma manera que una función.La diferencia se puede ver imprimiendo
get_defined_functions(): no hay ningunaprintfunción en la lista. (Aunque losprintfamigos son: a diferenciaprint, son funciones verdaderas).¿Por qué funciona print (foo) entonces?
Por la misma razón que
echo(foo)funciona. Estos paréntesis son bastante diferentes de los paréntesis de llamadas a funciones porque pertenecen a expresiones en su lugar. Es por eso que uno puede codificarecho ( 5 + 8 )y esperar que se muestre un resultado de 13 (ver referencia ). Estos paréntesis están involucrados en la evaluación de una expresión en lugar de invocar una función. Nota: hay otros usos para paréntesis en PHP, como expresiones if-conditional, listas de asignación, declaraciones de funciones, etc.¿Por qué hacer
print(1,2,3)yecho(1,2,3)dar lugar a errores de sintaxis?La sintaxis es
print expr,echo exproecho expr, expr, ..., expr. Cuando PHP se encuentra(1,2,3), intenta analizarlo como una sola expresión y falla, porque a diferencia de C, PHP realmente no tiene un operador de coma binario; la coma sirve más como separador. (No obstante, puede encontrar una coma binaria en los bucles for de PHP, sintaxis que heredó de C.)Semántica
La declaración
echo e1, e2, ..., eN;puede entenderse como azúcar sintáctica paraecho e1; echo e2; ...; echo eN;.Como todas las expresiones son declaraciones y
echo esiempre tienen los mismos efectos secundarios queprint e, y el valor de retorno deprint ese ignora cuando se usa como una declaración, podemos entenderloecho ecomo azúcar sintáctica paraprint e.Estas dos observaciones significan que
echo e1, e2, ..., eN;puede verse como azúcar sintáctica paraprint e1; print e2; ... print eN;. (Sin embargo, tenga en cuenta las diferencias de tiempo de ejecución no semánticas a continuación).Por lo tanto, solo tenemos que definir la semántica para
print.print e, cuando se evalúa:ey convierte el valor resultante en una cadenas. (Por lo tanto,print ees equivalente aprint (string) e).sal búfer de salida (que eventualmente se transmitirá a la salida estándar).1.Diferencias a nivel de bytecode
printimplica una pequeña sobrecarga de poblar la variable de retorno (pseudocódigo)echocompilaciones individuales en un código de operación:echocompilaciones de múltiples valores para múltiples códigos de operaciónTenga en cuenta que el valor múltiple
echono concatena sus argumentos, sino que los genera uno por uno.Referencia:
zend_do_print,zend_do_echo.Diferencias de tiempo de ejecución
ZEND_PRINTse implementa de la siguiente manera (pseudocódigo)Por lo tanto, básicamente coloca
1la variable de resultado y delega el trabajo real alZEND_ECHOcontrolador.ZEND_ECHOhace lo siguientedonde
zend_print_variable()realiza la "impresión" real (de hecho, simplemente redirige a una función SAPI dedicada).Velocidad:
echo xvsprint xA diferencia de echo , print asigna una variable temporal. Sin embargo, la cantidad de tiempo dedicado a esta actividad es minúscula, por lo que la diferencia entre estas dos construcciones de lenguaje es insignificante.
Velocidad:
echo a,b,cvsecho a.b.cEl primero se resume en tres declaraciones separadas. El segundo evalúa la expresión completa.
a.b.c., imprime el resultado y lo elimina de inmediato. Dado que la concatenación implica asignaciones de memoria y copia, la primera opción será más eficiente.Entonces, ¿cuál usar?
En aplicaciones web, la salida se concentra principalmente en plantillas. Dado que las plantillas usan
<?=, que es el alias deecho, parece lógico seguirechoen otras partes del código también.echotiene una ventaja adicional de poder imprimir múltiples expresiones sin concatenarlas y no implica una sobrecarga de llenar una variable de retorno temporal. Entonces, useecho.fuente
echo $a,$b,$cpara la concatenación de cadenas vars? Sinceramente, nunca he visto esto en uso.printpermite solo un argumento,echopuede tener múltiples;echono puede ser parte de una expresión mientrasprintcan y devuelve ...; y puede haber algún resumen de rendimiento. Y todas esas partes de "por qué" y "bajo el capó" despuésSé que llego tarde, pero una cosa que me gustaría agregar es que en mi código
da un error "error de sintaxis, 'eco' inesperado (T_ECHO)"
mientras
funciona bien.
Los documentos sobre echo dicen "echo (a diferencia de otras construcciones de lenguaje) no se comporta como una función" aquí, pero acerca de print docs también dice "print no es realmente una función real (es una construcción de lenguaje)" aquí . Entonces no estoy seguro de por qué. Y también sobre echo e print docs dice "Las principales diferencias con echo son que print solo acepta un argumento y siempre devuelve 1". aquí
Sería feliz si alguien puede arrojar algo de luz sobre este comportamiento.
fuente