Ссылка: Сравнение печати PHP и эха
В чем разница между PHP print
а также echo
?
У переполнения стека много вопросов о PHP print
а также echo
использование ключевых слов.
Цель этого поста - предоставить канонический справочный вопрос и ответ о PHP print
а также echo
ключевые слова и сравнить их различия и варианты использования.
1 ответ
Почему две конструкции?
Правда о печати и эхо заключается в том, что, хотя они представляются пользователям в виде двух отдельных конструкций, они действительно являются оттенками эха, если вы приступите к основам, то есть посмотрите на внутренний исходный код. Этот исходный код включает в себя как синтаксический анализатор, так и обработчики кода операции. Рассмотрим простое действие, например отображение нуля. Используете ли вы echo или print, будет вызываться один и тот же обработчик " ZEND_ECHO_SPEC_CONST_HANDLER". Обработчик для печати делает одну вещь, прежде чем он вызывает обработчик для эха, он гарантирует, что возвращаемое значение для печати равно 1, следующим образом:
ZVAL_LONG(&EX_T(opline->result.var).tmp_var, 1);
(см. здесь для справки)
Возвращаемое значение - удобство, если вы хотите использовать print в условном выражении. Почему 1, а не 100? В PHP истинность 1 или 100 одинакова, то есть истинна, тогда как 0 в логическом контексте приравнивается к ложному значению. В PHP все ненулевые значения (положительные и отрицательные) являются истинными значениями, и это вытекает из наследства PHP в Perl.
Но если это так, то можно задаться вопросом, почему echo принимает несколько аргументов, тогда как print может обрабатывать только один. Для этого ответа нам нужно обратиться к парсеру, а именно к файлу zend_language_parser.y. Вы заметите, что в echo встроена гибкость, позволяющая печатать одно или несколько выражений (см. Здесь). в то время как печать ограничена печатью только одного выражения (см. там).
Синтаксис
В языке программирования C и языках, на которые он влияет, таких как PHP, существует различие между утверждениями и выражениями. Синтаксически, echo expr, expr, ... expr
это заявление в то время как print expr
является выражением, поскольку оно оценивается как значение. Поэтому, как и другие заявления, echo expr
стоит сам по себе и не может быть включен в выражение:
5 + echo 6; // syntax error
По сравнению, print expr
, может в одиночку составить заявление:
print 5; // valid
Или, будьте частью выражения:
$x = (5 + print 5); // 5
var_dump( $x ); // 6
Можно подумать о print
как будто это был унарный оператор, как !
или же ~
однако это не оператор. Какие !, ~ and print
Общим является то, что все они встроены в PHP и каждый принимает только один аргумент. Ты можешь использовать print
создать следующий странный, но правильный код:
<?php
print print print print 7; // 7111
На первый взгляд результат может показаться странным, что последний оператор print сначала печатает свой операнд '7'. Но если вы копаете глубже и смотрите на действительные коды операций, это имеет смысл:
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
Самый первый генерируемый код операции соответствует коду "print 7". "~0" - это временная переменная, значение которой равно 1. Эта переменная становится операндом для следующего кода операции печати, который, в свою очередь, возвращает временную переменную, и процесс повторяется. Последняя временная переменная вообще не используется, поэтому она освобождается.
Почему print
вернуть значение и echo
не делает?
Выражения оценивают до значений. Например 2 + 3
оценивает 5
, а также abs(-10)
оценивает 10
, поскольку print expr
само по себе является выражением, то оно должно содержать значение, и это, постоянное значение 1
указывает на достоверный результат и, возвращая ненулевое значение, выражение становится полезным для включения в другое выражение. Например, в этом фрагменте возвращаемое значение print полезно при определении последовательности функций:
<?php
function bar( $baz ) {
// other code
}
function foo() {
return print("In and out ...\n");
}
if ( foo() ) {
bar();
}
Вы можете найти печать определенного значения, когда дело доходит до отладки на лету, как показано в следующем примере:
<?php
$haystack = 'abcde';
$needle = 'f';
strpos($haystack,$needle) !== FALSE OR print "$needle not in $haystack";
// output: f not in abcde
Как примечание, как правило, заявления не являются выражениями; они не возвращают значение. Исключением, конечно же, являются операторы выражений, которые используют print и даже простые выражения, используемые в качестве операторов, такие как 1;
синтаксис, который PHP наследует от C. Оператор выражения может выглядеть странно, но это очень полезно, позволяя передавать аргументы функциям.
Является print
функция?
Нет, это языковая конструкция. Хотя все вызовы функций являются выражениями, print (expr)
является выражением, несмотря на визуальный элемент, который выглядит так, как если бы он использовал синтаксис вызова функции. По правде говоря, эти скобки представляют собой синтаксис скобок-expr, полезный для вычисления выражений. Это объясняет тот факт, что иногда они являются необязательными, если выражение является простым, например, print "Hello, world!"
, С более сложным выражением, таким как print (5 ** 2 + 6/2); // 28
скобки помогают оценить выражение. В отличие от имен функций, print
синтаксически является ключевым словом, а семантически "языковой конструкцией".
Термин "языковая конструкция" в PHP обычно относится к "псевдо" функциям, таким как isset
или же empty
, Хотя эти "конструкции" выглядят в точности как функции, они на самом деле являются fexprs, то есть аргументы передаются им без оценки, что требует особой обработки от компилятора. print
случается, что fexpr, который выбирает для оценки своего аргумента так же, как функции.
Разницу можно увидеть по распечатке get_defined_functions()
: здесь нет print
функция в списке. (Хоть printf
а друзья такие print
, они истинные функции.)
Почему print(foo) работает тогда?
По той же причине, что echo(foo)
работает. Эти круглые скобки сильно отличаются от круглых скобок вызова функции, потому что вместо этого они относятся к выражениям. Вот почему можно кодировать echo ( 5 + 8 )
и может ожидать результат 13 для отображения (см. ссылку). Эти круглые скобки участвуют в оценке выражения, а не в вызове функции. Примечание: в PHP есть другие варианты использования скобок, такие как условные выражения if, списки присваивания, объявления функций и т. Д.
Почему print(1,2,3)
а также echo(1,2,3)
привести к синтаксическим ошибкам?
Синтаксис print expr
, echo expr
или же echo expr, expr, ..., expr
, Когда PHP встречает (1,2,3)
он пытается разобрать его как одно выражение и завершается неудачно, потому что в отличие от C, PHP на самом деле не имеет двоичного оператора запятой; запятая служит в качестве разделителя. (Тем не менее, вы можете найти двоичную запятую в циклах for PHP, синтаксис которой унаследован от C.)
Семантика
Заявление echo e1, e2, ..., eN;
можно понимать как синтаксический сахар для echo e1; echo e2; ...; echo eN;
,
Поскольку все выражения являются заявлениями, и echo e
всегда имеет те же побочные эффекты, что и print e
и возвращаемое значение print e
игнорируется при использовании в качестве заявления, мы можем понять echo e
как синтаксический сахар для print e
,
Эти два наблюдения означают, что echo e1, e2, ..., eN;
можно рассматривать как синтаксический сахар для print e1; print e2; ... print eN;
, (Тем не менее, обратите внимание на несемантические различия во время выполнения ниже.)
Поэтому нам нужно только определить семантику для print
, print e
при оценке:
- оценивает свой единственный аргумент
e
и вводит полученное значение в строкуs
, (Таким образом,print e
эквивалентноprint (string) e
.) - Потоки строки
s
в выходной буфер (который в конечном итоге будет передаваться на стандартный вывод). - Оценивает в целое число
1
,
Отличия на уровне байт-кода
print
включает небольшие накладные расходы на заполнение возвращаемой переменной (псевдокод)
print 125;
PRINT 125,$temp ; print 125 and place 1 in $temp
UNSET $temp ; remove $temp
не замужем echo
компилируется в один код операции:
echo 125;
ECHO 125
многозначное echo
компилируется в несколько операционных кодов
echo 123, 456;
ECHO 123
ECHO 456
Обратите внимание, что многозначный echo
не объединяет свои аргументы, а выводит их один за другим.
Ссылка: zend_do_print
, zend_do_echo
,
Различия во время выполнения
ZEND_PRINT
реализован следующим образом (псевдокод)
PRINT var, result:
result = 1
ECHO var
Так что в основном ставит 1
в переменной результата и делегирует реальную работу ZEND_ECHO
обработчик. ZEND_ECHO
делает следующее
ECHO var:
if var is object
temp = var->toString()
zend_print_variable(temp)
else
zend_print_variable(var)
где zend_print_variable()
выполняет фактическую "печать" (фактически она просто перенаправляет на выделенную функцию SAPI).
Скорость: echo x
против print x
В отличие от echo, print выделяет временную переменную. Тем не менее, количество времени, затрачиваемого на эту деятельность, незначительно, поэтому разница между этими двумя языковыми конструкциями незначительна.
Скорость: echo a,b,c
против echo a.b.c
Первый сводится к трем отдельным утверждениям. Второй оценивает все выражение a.b.c.
, печатает результат и немедленно удаляет его. Поскольку объединение включает в себя выделение памяти и копирование, первый вариант будет более эффективным.
Так какой из них использовать?
В веб-приложениях вывод в основном сконцентрирован в шаблонах. Поскольку шаблоны используют <?=
, который является псевдонимом echo
кажется логичным придерживаться echo
в других частях кода. echo
имеет дополнительное преимущество, заключающееся в возможности печатать несколько выражений без их объединения и не требует дополнительных затрат на заполнение временной возвращаемой переменной. Итак, используйте echo
,
Я знаю, что опоздал, но я хотел бы добавить, что в моем коде
$stmt = mysqli_stmt_init($connection) or echo "error at init";
выдает ошибку "синтаксическая ошибка, неожиданное" эхо "(T_ECHO)"
в то время как
$stmt = mysqli_stmt_init($connection) or print "error at init";
работает отлично.
В документах об echo говорится, что "echo (в отличие от некоторых других языковых конструкций) здесь не ведет себя как функция", но в документах print также говорится, что "печать на самом деле не является реальной функцией (это языковая конструкция)". Поэтому я не уверен, почему. В документах echo и print также говорится: "Основные отличия echo в том, что print принимает только один аргумент и всегда возвращает 1". Вот
Я был бы счастлив, если бы кто-нибудь мог пролить свет на это поведение.
print
может существовать как утверждение без необходимости;, и это причина, по которой мы можем включить его в
$b; print "TRUE": print "FALSE";