以下代码输出43211
,为什么?
echo print('3').'2'.print('4');
答案 0 :(得分:14)
您的语句将解析为人,如下所示。
回显由以下内容组成的串联字符串:
print('3')
的结果,它将返回true,并将其字符串化为1
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如何解析这些废话。我不会再考虑它了,它伤害了我的大脑。
答案 1 :(得分:3)
大部分混淆是由于在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"
。答案 2 :(得分:2)
答案 3 :(得分:0)
你正在使用函数中的函数,如亚历克斯所说。只需使用echo或print。
echo '3'.'2'.'4';
将正确返回或同样返回打印。