我在php.net的print manual中遇到过一个例子。那个统计数据。
echo 3 . print(2) . print(4) . 5 . 'c' .
print(6) . print(7). 'b' .print(8) . 'a';
打印8a7b16145c12131
。但是如何?
答案 0 :(得分:3)
我认为你刚刚被连接运算符.
的存在所迷惑,这使得你假设这段代码的唯一输出来自echo
而所有其他函数只会“贡献”到echo的参数。当然,这是错误的,因为你假设print()
以某种方式改变了它的行为并且返回其输出,而不是立即打印(通话时) )到输出流。你连接的唯一东西是字符串,每个print()
的**返回值**。而后者,according to the manual 总是“1”。将print()
更改为sprintf()
,所有“魔法”都将消失。
编辑OP的请求
这里的“罪魁祸首”是print
。值得注意的是,它不是一个真正的功能,而是语言构造,它会影响评估过程中的处理方式。例如:
echo 3 . print(2) . 'c';
产生
2c31
但是如果你将print
移动到这样的函数中:
function x($a) { return print $a; }
echo 3 . x(2) . 'c';
然后输出看起来更健全:
231c
如果您关心细节,则需要潜入Zend Engine源代码,但一般来说,这种语法可能用于任何有用的东西。记住print
非常棘手。
为什么我们看到“231c”呢?这是因为echo
参数首先需要被评估 - 没有PHP不知道要回应什么(或者可以知道部分)。所以PHP以这种方式更多/更少:
x(2)
- 由于此函数执行print
,我们的参数(“2”)将立即打印到输出。函数返回“1”,因为print
总是返回“1”(参见手册)所以PHP连接“1”,所以我们现在有“31”,echo
我们的临时字符串。 请注意,实际上echo
仅输出'31c'。前缀“2”是因为它是print
输出而我们没有使用LF(或<br />
如果你没有在控制台中测试它)同时所有输出都进入一行。如果您将代码更改为使用LF(或<br />
):
function x($a) { return print $a; }
$f = 3 . x(2) . 'c';
echo "\n${f}";
然后输出将是:
2
31c
希望这有帮助。
答案 1 :(得分:0)
它打印'8'与'a'连接,依此类推,从右到左,如手册所示。回声打印'1'
例如
<?php
echo print(8) . 'a';
?>
打印8a1