Следующий код выводит 43211
, почему?
echo print('3').'2'.print('4');
Ваше заявление анализирует людей следующим образом.
Эхо-конкатенированная строка, состоящая из:
print('3')
, который вернет true, который будет привязан к 1
print('4')
, который вернет true, который будет привязан к 1
Теперь порядок операций здесь действительно смешной, и это никак не может быть 43211
с 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
.
Я бы предпочел не повторять результат print
и не print
результаты echo
. Для этого совершенно бессмысленно.
После дальнейшего рассмотрения я на самом деле не совсем уверен, как PHP разбирает любой из этих кусков глупостей. Я больше не буду об этом думать, это больно моему мозгу.
Большая часть путаницы связана с размещением круглых скобок вокруг аргументов для 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
доказательство
Вы можете подтвердить это поведение, когда смотрите на коды операций, которые сгенерированы (выходной столбец добавлен для ясности):
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"
из-за струнного литья. print
возвращается 1
О документации
Возвращаемые значения: Возвращает 1, всегда.
Вероятно, вы просто должны использовать echo
.
Вы используете функцию внутри функции, как сказал alex. Просто используйте эхо или печать.
echo '3'.'2'.'4';
вернется правильно или аналогично для печати.