PHP内核编译if语句

我们有如下脚本:

1
2
3
4
5
6
7
8
9
<?php

$i = 4;

if ($i < 5) {
echo 1;
} else {
echo 2;
}

对应的opcode为:

1
2
3
4
5
6
7
L3    #0     ASSIGN                  $i                   4
L5 #1 IS_SMALLER $i 5 ~1
L5 #2 JMPZ ~1 J5
L6 #3 ECHO 1
L6 #4 JMP J6
L8 #5 ECHO 2
L10 #6 RETURN<-1> 1

首先,我们把if语句的组成部分说一下(当然,这是一个没有包含递归的语法,简化版):

1
T_IF '(' cond_expr ')' true_statement T_ELSE false_statement

对应:

1
2
3
4
5
T_IF => if
cond_exprs => $i < 5
true_statement => echo 1;
T_ELSE => else
false_statement => echo 2;

OK,我们来从编译出来的opcode总结出编译for语句的一般规律:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
   ┌─────────────────────────────────┐   
│ │
│ │
│ cond_exprs │
│ │
│ │
└─────────────────────────────────┘




┌─────────────────────────────────┐
│ │
│ │
│ JMPZ │──┐
│ │ │
│ │ │
└─────────────────────────────────┘ │
│ │
│ │
│ │
▼ │
┌─────────────────────────────────┐ │
│ │ │
│ │ │
│ true_statement │ │
│ │ │
│ │ │
└─────────────────────────────────┘ │
│ │
│ │
│ │
▼ │
┌─────────────────────────────────┐ │
│ │ │
│ │ │
┌──│ JMP │ │
│ │ │ │
│ │ │ │
│ └─────────────────────────────────┘ │
│ │ │
│ │ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────┐ │
│ │ │ │
│ │ │ │
│ │ false_statement │◀─┘
│ │ │
│ │ │
│ └─────────────────────────────────┘
│ │
│ │
│ │
│ │
│ ▼
│ ┌─────────────────────────────────┐
│ │ │
│ │ │
└─▶│ out_if_stmt │
│ │
│ │
└─────────────────────────────────┘