PHP怎么看源码

Categories: 工具语言
Tags: , , ,
Comments: 1 Comment
Published on: 2015 年 07 月 17 日


如何看php的源码,很简单,这里给一个样例,先写一个php

1
2
3
<?php
empty($a);
isset($a);

然后可以通过php vld扩展查看opcode,可以发现opcode:

2 0 E > ISSET_ISEMPTY_VAR 293601280 RES[ IS_TMP_VAR ~0 ] OP1[ IS_CV !0 ] OP2[ IS_UNUSED ]
1 FREE OP1[ IS_TMP_VAR ~0 ]
3 2 ISSET_ISEMPTY_VAR 310378496 RES[ IS_TMP_VAR ~1 ] OP1[ IS_CV !0 ] OP2[ IS_UNUSED ]
3 FREE OP1[ IS_TMP_VAR ~1 ]
4 4 > RETURN OP1[ IS_CONST (128414056) 1 ]

均调用了:ISSET_ISEMPTY_VAR , 然后去zend源码文件内执行shell命令:
grep -r "ISSET_ISEMPTY_VAR" ./
可以顺藤摸瓜的找到这个op执行的是ZEND_ISSET_ISEMPTY_VAR(zend_vm_opcodes.c),
然后找到ZEND_ISSET_ISEMPTY_VAR实际到execute的时候执行的是ZEND_ISSET_ISEMPTY_VAR_xxx(zend_vm_execute.h)等一系列函数,通过源码阅读发现判断变量是否为空的最终执行函数是:i_zend_is_true(),
最终找到定义的地方:zend_execute.h:static zend_always_inline int i_zend_is_true(zval *op);
具体代码如下:

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
static zend_always_inline int i_zend_is_true(zval *op)
{
        int result;
 
        switch (Z_TYPE_P(op)) {
                case IS_NULL:
                        result = 0;
                        break;
                case IS_LONG:
                case IS_BOOL:
                case IS_RESOURCE:
                        result = (Z_LVAL_P(op)?1:0);
                        break;
                case IS_DOUBLE:
                        result = (Z_DVAL_P(op) ? 1 : 0);
                        break;
                case IS_STRING:
                        if (Z_STRLEN_P(op) == 0
                                || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {
                                result = 0;
                        } else {
                                result = 1;
                        }
                        break;
                case IS_ARRAY:
                        result = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
                        break;
                case IS_OBJECT:
                        if(IS_ZEND_STD_OBJECT(*op)) {
                                TSRMLS_FETCH();
 
                                if (Z_OBJ_HT_P(op)->cast_object) {
                                        zval tmp;
                                        if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, IS_BOOL TSRMLS_CC) == SUCCESS) {
                                                result = Z_LVAL(tmp);
                                                break;
                                        }
                                } else if (Z_OBJ_HT_P(op)->get) {
                                        zval *tmp = Z_OBJ_HT_P(op)->get(op TSRMLS_CC);
                                        if(Z_TYPE_P(tmp) != IS_OBJECT) {
                                                /* for safety - avoid loop */
                                                convert_to_boolean(tmp);
                                                result = Z_LVAL_P(tmp);
                                                zval_ptr_dtor(&tmp);
                                                break;
                                        }
                                }
                        }
                        result = 1;
                        break;
                default:
                        result = 0;
                        break;
        }
        return result;
}

我猜你可能也喜欢:

1 Comment - Leave a comment
  1. 唯美句子说道:

    这分析精神值得学习!!

Leave a comment

电子邮件地址不会被公开。 必填项已用*标注

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>


Welcome , today is 星期日, 2017 年 11 月 19 日