PHP源码阅读 Day.1,源码目录结构分析

来源:互联网 发布:河南省南乐县网络电视 编辑:程序博客网 时间:2024/05/17 04:59
作为一个已经工作很久的PHP程序员,对于PHP各种框架以及实现原理已经摸的很熟悉了,我之前是做java开发的,一直保留了java的开发思想,并且工作中也还在使用javaweb写项目,也使用比较成熟的IOC,AOP思想写了PHP框架,但是总感觉还是不够太了解PHP,于是有去了解了CGI,FastCGI,PHP-FPM,PHP-CGI,了解了他们的工作原理感觉还是不够,又去熟悉PHP与apache,nginx如何工作的其实就靠了个sapi进行来回工作,即使这样感觉还是不太了解PHP,当时做java的时候我经常去研究jvm里面是怎么工作的,所以PHP我感觉我也要去读下源码,毕竟PHP的源码是C写的,还是比较容易接受,于是就下载了PHP的源码开始阅读。
Day .No1
读取源码需要了解PHP的源码结构,PHP的源码结构比较清晰:

|_ ext php一些扩展存放目录
|_main PHP的一些内建函数
|_pear
|_sapi spai提供了一个和外部通信的接口与apache,nginx进行协同工作
|_tests php的一些demo
|_TSRM
|_Zend zend虚拟的实现

先从zend文件夹开始阅读
1.php的基本类型在C里面是如何实现的?
找到zend文件夹下面有一个头文件zend_types.h
typedef struct_zval_struct zval;typedef struct_zend_class_entry zend_class_entry;typedef struct_zend_refcounted zend_refcounted;typedef struct_zend_string zend_string;typedef struct_zend_array zend_array;typedef struct_zend_object zend_object;

上面这些就是我们平常使用到的,对象,数组,变量,还有gc的结构体定义,看了之后发现PHP里面的任何类型都是C里面的一个结构体(struct)
typedef union _zend_value {    zend_long lval;             /* long value */    double dval;             /* double value */    zend_refcounted *counted;    zend_string *str;    zend_array *arr;    zend_object *obj;    zend_resource *res;    zend_reference *ref;    zend_ast_ref *ast;    zval *zv;    void *ptr;    zend_class_entry *ce;    zend_function *func;    struct {        uint32_t w1;        uint32_t w2;    } ww;} zend_value;

zend内部针对php的操作类型定义了一个union类型
我对C语言只是在学校期间学过简单语法,于是在看代码过程又学习这些语法什么意思。

typedef 意思是定义一个类型的别名
例子:
#include <stdio.h>void main(){typedef int Integer;Integer x=1;Integer y=2;printf("sum= %d",x+y);}

typedef 我理解起来就是为了方便我们写代码的习惯,我熟悉java习惯了Integer 所以可以定义别名,提高写代码的效率。
struct 是C语言里面的结构体
#include <stdio.h>typedef struct person{char name[20];int age;}p;void main(){p per;per.name[4] = "gxx";per.age = 12;printf("姓名:%s,年龄:%d",per.name,per.age);}

上面就是C语言里面的结构体定义以及对成员赋值,有点像我们平常使用的对象定义一些属性,并进行赋值。

ext文件夹下面存放的是php的扩展,里面有一个标准扩展 standard 文件夹,下面找到array.c文件是具体array里面方法操作的实现,找到php_array.h文件
PHP_FUNCTION(ksort);PHP_FUNCTION(krsort);PHP_FUNCTION(natsort);PHP_FUNCTION(natcasesort);PHP_FUNCTION(asort);PHP_FUNCTION(arsort);PHP_FUNCTION(sort);PHP_FUNCTION(rsort);PHP_FUNCTION(usort);PHP_FUNCTION(uasort);PHP_FUNCTION(uksort);列举一部分,就是定义的PHP里面的方法。staticvoidphp_splice(HashTable*in_hash, zend_long offset, zend_long length, HashTable*replace, HashTable*removed)/* {{{ */{    HashTable    out_hash;}

其实c语言针对php数组的操作是使用hashtable实现的。
PHP_FUNCTION(krsort){    zval*array;    zend_long sort_type= PHP_SORT_REGULAR;    compare_func_t cmp;    ZEND_PARSE_PARAMETERS_START(1,2)        Z_PARAM_ARRAY_EX(array,0,1)        Z_PARAM_OPTIONAL        Z_PARAM_LONG(sort_type)    ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);    cmp=php_get_key_compare_func(sort_type,1);    if (zend_hash_sort(Z_ARRVAL_P(array), cmp, 0)== FAILURE) {        RETURN_FALSE;    }    RETURN_TRUE;}

在zend文件夹下面的zend_hash.h文件里面 就能找到
#definezend_hash_sort(ht, compare_func, renumber)宏定义
所以数组的操作都是hashtable实现的。

阅读的过程发现了一个do {...}while(0)的用法挺好奇的就查了下什么含义。
例子:
#define DOSOMETHING()\ foo1();\ foo2();
调用
if(a>0) DOSOMETHING()
宏的预处理会直接被展开
if(a>0)   foo1(); foo2();
所以不是我们预期想要的结果。
我们这样定义之后再执行结果
#define DOSOMETHING() \ do{ \ foo1();\ foo2();\ }while(0)\
执行:
if(a>0){   foo1();   foo2();};

这才是我们想要的结果。
0 0
原创粉丝点击