Странное эхо, поведение печати в PHP? - PullRequest
3 голосов
/ 27 июля 2010

Следующий код выводит 43211, почему?

  echo print('3').'2'.print('4');

Ответы [ 4 ]

14 голосов
/ 27 июля 2010

Ваше утверждение анализирует для людей следующим образом.

Выводит объединенную строку, состоящую из:

  1. Результат функции print('3'), которая будет возвращать true, которая преобразуется в 1
  2. Строка '2'
  3. Результат функции print('4'), которая будет возвращать true, которая преобразуется в 1

Теперь порядок операций здесь действительно забавный, который не может закончиться 43211! Давайте попробуем вариант, чтобы выяснить, что происходит не так.

echo '1' . print('2') . '3' . print('4') . '5';

Это дает 4523111

PHP анализирует это, затем, как:

echo '1' . (print('2' . '3')) . (print('4' . '5'));

Бинго! print слева оценивается первым, печатается '45', что оставляет нас

echo '1' . (print('2' . '3')) . '1';

Затем оценивается левый print, поэтому мы напечатали '4523', оставив нам

echo '1' . '1' . '1';

Успех. 4523111.

Давайте разберем ваше утверждение о странности.

echo print('3') . '2' . print('4');

Сначала будет напечатано '4', а у нас будет

echo print('3' . '2' . '1');

Затем вычисляется следующий оператор печати, что означает, что мы теперь напечатали '4321', оставив нам

echo '1';

Таким образом, 43211.

Я бы настоятельно рекомендовал не echo выводить результат print или print выводить результат echo. Это очень бессмысленно для начала.


После дальнейшего рассмотрения я на самом деле не совсем уверен, как PHP анализирует эти биты чепухи. Я не буду больше думать об этом, это ранит мой мозг.

3 голосов
/ 18 октября 2012

Большая часть путаницы происходит из-за размещения скобок вокруг аргументов print.Как вы знаете, скобки являются необязательными для языковых конструкций;что вы, вероятно, не знали, так это то, что они удаляются во время синтаксического анализа.

Порядок оценки

Давайте сначала удалим скобки:

echo print '3' . '2' . print '4';

И проиллюстрируйте действительный порядок оценки:

echo (print ('3' . '2' . (print '4')))
^     ^      ^                     ^
3     2      1--------->>----------1

В основе этого вы найдете объединение строк или строковых представлений;сначала оценивается:

'3' . '2' . (print '4')

Первые два элемента объединяются:

'32' . (print '4')

Затем оценивается значение (print '4');после вывода аргумента '4' возвращаемое значение самого print всегда равно int(1);он преобразуется в строку '1' и объединяется с другими элементами:

'321'

На этом завершается первый шаг.Второй шаг передает временные результаты другому оператору print:

print '321'

Как и раньше, печатается '321', и теперь для последнего шага возвращается int(1):

echo 1

Proof

Вы можете подтвердить это поведение, посмотрев на сгенерированные коды операций (для ясности добавлен выходной столбец):

line     # *  op          return  operands        output
------------------------------------------------+-------
   1     0  >   CONCAT      ~0      '3', '2'    |
         1      PRINT       ~1      '4'         | 4
         2      CONCAT      ~2      ~0, ~1      | 4
         3      PRINT       ~3      ~2          | 4321
         4      ECHO        ~3                  | 43211

Пояснение

  • "3" и "2" объединены - "32" - и сохранены в ~0.
  • "4" и напечатано возвращаемое значение int(1) сохраняется в ~1.
  • ~0 и ~1 объединяются - "321" - и сохраняются в ~2.
  • "321", печатаются и возвращаютсязначение сохраняется в ~3.
  • int(1) печатается как "1" из-за приведения строки.
2 голосов
/ 27 июля 2010

print возвращается 1

В документации

Возвращаемые значения: всегда возвращает 1.

Вероятно, вам следует придерживаться echo.

0 голосов
/ 27 июля 2010

Вы используете функцию внутри функции, как сказал Алекс. Просто используйте echo или print.

echo '3'.'2'.'4'; 

будет возвращаться правильно или аналогично для печати. ​​

...