今天在群里无意间看到一个网友问的一个问题

$a=$b=0;
if($a=0 || $b =2)
{
var_dump($a,$b);
}

输出:
bool(true)
int(2)

谁能解释一下$a 为什么是true?

我对这个问题也挺好奇…开始没有想到优先级
后来用vld翻开PHP执行生成的OP来观察,才发现..是优先级的问题

 

   
   
   
   
  1. number of ops:  12 
  2. compiled vars:  !0 = $a, !1 = $b 
  3. line     # *  op                           fetch          ext  return  operands 
  4. --------------------------------------------------------------------------------- 
  5.    2     0  >   ASSIGN                                            RES[  IS_VAR $0 ]       OP1[  IS_CV !1 ] OP2[ ,  IS_CONST (0) 0 ] 
  6.          1      ASSIGN                                                    OP1[  IS_CV !0 ] OP2[ ,  IS_VAR $0 ] 
  7.    3     2    > JMPNZ_EX                                          RES[  IS_TMP_VAR ~2 ]       OP1[  IS_CONST (0) 0 ] OP2[ , ->5 ] 
  8.          3  >   ASSIGN                                            RES[  IS_VAR $3 ]       OP1[  IS_CV !1 ] OP2[ ,  IS_CONST (0) 2 ] 
  9.          4      BOOL                                              RES[  IS_TMP_VAR ~2 ]       OP1[  IS_VAR $3 ] 
  10.          5  >   ASSIGN                                            RES[  IS_VAR $4 ]       OP1[  IS_CV !0 ] OP2[ ,  IS_TMP_VAR ~2 ] 
  11.          6    > JMPZ                                                      OP1[  IS_VAR $4 ] OP2[ , ->11 ] 
  12.    4     7  >   SEND_VAR                                                  OP1[  IS_CV !0 ] 
  13.          8      SEND_VAR                                                  OP1[  IS_CV !1 ] 
  14.          9      DO_FCALL                                      2           OP1[  IS_CONST (34085885) 'var_dump' ] 
  15.    5    10    > JMP                                                       OP1[ ->11 ] 
  16.   15    11  > > RETURN                                                    OP1[  IS_CONST (0) 1 ] 

下面这段代码

 

   
   
   
   
  1. 2     0  >   ASSIGN                                            RES[  IS_VAR $0 ]       OP1[  IS_CV !1 ] OP2[ ,  IS_CONST (0) 0 ] 
  2.       1      ASSIGN                                                    OP1[  IS_CV !0 ] OP2[ ,  IS_VAR $0 ] 

没有异议,如果熟悉PHP内核的人一看就知道 ASSIGN 就是给变量赋值
对应的是 $a=$b=0;
重点就在这里了

 

   
   
   
   
  1. 3     2    > JMPNZ_EX                                          RES[  IS_TMP_VAR ~2 ]       OP1[  IS_CONST (0) 0 ] OP2[ , ->5 ] 
  2.       3  >   ASSIGN                                            RES[  IS_VAR $3 ]       OP1[  IS_CV !1 ] OP2[ ,  IS_CONST (0) 2 ] 
  3.       4      BOOL                                              RES[  IS_TMP_VAR ~2 ]       OP1[  IS_VAR $3 ] 
  4.       5  >   ASSIGN                                            RES[  IS_VAR $4 ]       OP1[  IS_CV !0 ] OP2[ ,  IS_TMP_VAR ~2 ] 
  5.       6    > JMPZ                                                      OP1[  IS_VAR $4 ] OP2[ , ->11 ] 

||在PHP里被解析成JMPNZ_EX 这里先执行了||

IS_TMP_VAR 是临时变量的意思 这里保存一个临时变量 ~2它的值是 0

   
   
   
   
  1. ASSIGN                                            RES[  IS_VAR $3 ]       OP1[  IS_CV !1 ] OP2[ ,  IS_CONST (0) 2 ] 

这句代码执行的是 $b=2; 然后保存到变量 $3里.
BOOL RES[ IS_TMP_VAR ~2 ] OP1[ IS_VAR $3 ]
$3与 临时变量~2比较
也就是执行了代码 $3||0 ,返回的值~2肯定是真

 

   
   
   
   
  1. ASSIGN                                            RES[  IS_VAR $4 ]       OP1[  IS_CV !0 ] OP2[ ,  IS_TMP_VAR ~2 ] 

最后 ~2的值 赋给$a;
这个时候 $a 和 $b的值都为真
那么 var_dump输出 true 也就是理所应当的事了..

原文出处: http://www.imsiren.com/archives/193