今天lamper群里一个兰帕儿问起一段代码:
$a = 3; $b = 4; if($a = 5 || $b = 5) { echo $a.$b; }
输出是14。
对着答案分析了半天也没分析出个什么结果,最后想到鸟哥之前介绍过的opcode,索性用opcode来解决这些语法问题了。
要dump出opcode需要php extension vld,安装方法如下:
# wget http://pecl.php.net/get/vld-0.10.1.tgz # tar zxvf vld-0.10.1.tgz # cd ./vld-0.10.1 # ./configure --with-php-config=/*your php-config path*/ --enable-vld # make && make install
然后,向php.ini中添加如下代码:
extension=vld.so
整个安装过程就完成了。
使用方法:
命令行中运行
php -dvld.active=1 /*your php file*/.php
好了现在回到之前的那个问题,dump出来的opcode如下:

从#0 #1可看出 !0 为代码中显式申请的$a,!1为$buo
#2是 jump to operand 2 if operand 1 is not null , 这里的1操作书只有一个5,而PHP代码中是 if($a = 5 || $b = 5) , 那么明显这里判断的是第一个 5
看到这里基本可以知道PHP是如何执行的了, php代码中 $a 是左操作数, 5 || $b = 5 一起作为右操作数(这也是情理之中的事情),而 ||是或运算,
先检查左边的(opcode中先检查左边是否为5),如果为真,则不会再执行右边的代码,因为真假都无所谓了整个表达式肯定为真。 最后返回真,所以
$a = 1, 而$b=5没被执行所以$b还是等于4,所以最后结果为14。
最后来看看 opcode 是如何解释这些代码的。
#0 #1 对应 php中的两个赋值语句。(个人理解opcode中以叹号+数字的形式出现的东西都是用户定义的变量,~和$+数字的形式是临时变量,用户没有进行申明)
#2 对应 if(5) goto #5 并且把BOOL(5)返回到~2 临时变量中。
#3 对应 $b = 5
#4 BOOL($b = 5) ,返回给临时变量 ~2中,那么现在~2实际上就是$a的值。
#5 $a = ~2
#6 if($a == 0) goto #10
#7 ~5 = $a.$b
#8 echo ~5
#9 goto #10
#10 return
浙公网安备 33010602011771号