【发布时间】:2016-07-20 05:12:59
【问题描述】:
我们有一段简单的代码:
1 <?php
2 $i = 2;
3 $j = &$i;
4 echo (++$i) + (++$i);
在 PHP5 上,它输出 8,因为:
$i 是一个引用,当我们将$i 增加++i 时,它会更改zval 而不是复制,所以第4 行将是4 + 4 = 8。这是通过引用分配。
如果我们注释第 3 行,它将输出 7,每次我们通过增加它来更改值,PHP 都会复制,第 4 行将是3 + 4 = 7。这是写入时复制。
但在 PHP7 中,它总是输出 7。
我检查了 PHP7 中的更改:http://php.net/manual/en/migration70.incompatible.php,但我没有得到任何线索。
任何帮助都会很棒,在此先感谢。
更新1
这是 PHP5 / PHP7 上的代码结果:https://3v4l.org/USTHR
更新2
操作码:
[huqiu@101 tmp]$ php -d vld.active=1 -d vld.execute=0 -f incr-ref-add.php
Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = -2
filename: /home/huqiu/tmp/incr-ref-add.php
function name: (null)
number of ops: 7
compiled vars: !0 = $i, !1 = $j
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
2 0 E > ASSIGN !0, 2
3 1 ASSIGN_REF !1, !0
4 2 PRE_INC $2 !0
3 PRE_INC $3 !0
4 ADD ~4 $2, $3
5 ECHO ~4
5 6 > RETURN 1
branch: # 0; line: 2- 5; sop: 0; eop: 6; out1: -2
path #1: 0,
【问题讨论】:
-
这闻起来像以前版本的 PHP 中的错误。
-
通过阅读文档,我没有看到保证任何评估顺序的明确声明,因此代码依赖于未指定的实现细节。说明:
++$i将首先递增$i,然后返回$i,根据文档。从变量$i到整数值(加号操作所必需的)的转换是发生在第二次递增操作之前还是之后没有定义。 -
嗨,@UlrichEckhardt 我更新了问题并添加了操作码,似乎增量在
ADD和ECHO之前。 -
我已经给php internals发了一封邮件,希望那里的人能给我一些线索。
-
我手头没有链接,但我清楚地记得 PHP 文档中声明无法保证评估顺序。
标签: php php-internals