第⼀章第⼀章 准准备⼯作和背景知⼯作和背景知识
千⾥之⾏,始于⾜下。千⾥之⾏,始于⾜下。
在开始进⼊PHP的内核实现之前,需要做⼀些准备⼯作,也需要了解⼀些背景知识。本章主要涉及
PHP源码的获取, PHP源码的编译,从⽽得到我们的调试环境。
接下来,我们将简单描述PHP源码的结构以及在*nix环境和Windows环境下如何阅读源码。 最后我们
介绍在阅读PHP源码过程中经常会遇到的⼀些语句。
如果你没有接触过PHP,或者对PHP的历史不太了解,我们推荐你先移步百度百科 PHP, 这⾥有PHP
⾮常详细的历史介绍,它包括PHP的诞⽣,PHP的发展,PHP的应⽤,PHP现有三⼤版本的介绍以及对于
PHP6的展望等。
⽬前PHP6已经停⽌开发了,PHP6的设计初衷是向后不兼容以及Unicode⽀持等。⽬前
很多特性已经在PHP5.3和PHP5.4中实现了:⽐如5.4中的traits,⽀持C#类似的getter&setter语
法(⽬前处在实现阶段), 基本类型的类型提⽰等。
下⾯,我们将介绍源码阅读环境的搭建。
第⼀第⼀节 环境搭建境搭建
在开始学习PHP实现之前,我们需要⼀个实验和学习的环境。下⾯介绍⼀下怎样在*nix环境下准备和搭
建PHP环境。
(*nix指的是类Unix环境,⽐如各种Linux发⾏版,FreeBSD, OpenSolaris, Mac OS X
等操作系统)
1.获取取PHP源源码
为了学习PHP的实现,⾸先需要下载PHP的源代码。下载源码⾸选是去PHP官⽅⽹站
http://php.net/downloads.php下载, 如果你喜欢使⽤svn/git等版本控制软件,也可以使⽤svn/git来获取最
新的源代码。
# git 官⽅地址
git clone https://git.php.net/repository/php-src.git
# 也可以访问github官⽅镜像
git clone git://github.com/php/php-src.git
cd php-src && git checkout origin PHP-5.3 # 签出5.3分⽀
# svn地址不变,不过不推荐从这⾥签出代码
cd ~
svn co http://svn.php.net/repository/php/php-src/branches/PHP_5_2 php-src-5.2
#5.2版本
svn co http://svn.php.net/repository/php/php-src/branches/PHP_5_3 php-src-5.3
#5.3版本
笔者⽐较喜欢⽤版本控制软件签出代码,这样做的好处是能看到PHP每次修改的内容及⽇志信息, 如
TIPI:深⼊理解PHP内核 RELEASE_2012-04-04_V0.7.3
果⾃⼰修改了其中的某些内容也能快速的查看到,如果你想修复PHP的某个Bug或者提交新功能的话, 有
版本控制也会容易的多,更多信息可以参考附录:怎样为PHP做贡献。
⽬前PHP已经迁移到Git了,PHP的wiki上有关于 迁移到Git的说明,以及使⽤Git的流程
在笔者编写这些内容的时候PHP版本控制是还基于SVN的,上⾯提到的github镜像地址⽬前已
经没有同步更新了, 由于把svn同步到git会对系统性能造成明显影响,加上社区还没有就到底
是否迁移到git达成⼀致,所以也就停⽌了更新。 ⽬前很多开源软件都开始转向了分布式版本
控制系统(DVCS), 例如Python语⾔在转向DVCS时对⽬前的分布式版本控制系统做了⼀个详
细的对⽐, 如果以前没有接触过,笔者强烈建议试试这些版本控制软件。现在Github的同步
基本是实时的。 所以习惯Github基本上可以把Github当做官⽅版本库了。
2.准准备编译环境境
在*nix环境下,需要安装编译构建环境。如果你⽤的是Ubuntu或者是⽤apt做为包管理的系统,可以通
过如下命令快速安装:
sudo apt-get install build-essential
如果你使⽤的是Mac OS,则需要安装Xcode。Xcode可以在Mac OS X的安装盘中找到,如果你有
Apple ID的话, 也可以登陆苹果开发者⽹站http://developer.apple.com/下载。
3. 编译
下⼀步可以开始编译了,本⽂只简单介绍基本的编译过程,不包含Apache的PHP⽀持以及Mysql等模
块的编译。 相关资料请⾃⾏查阅相关⽂档。 如果你是从svn/git签出的代码则需要执⾏代码根⽬录的
buildconf脚本以⽣成所需要的构建脚本。
cd ~/php-src
./buildconf
执⾏完以后就可以开始configure了,configure有很多的参数,⽐如指定安装⽬录,是否开启相关模块
等选项:
有的系统⾃带的autoconf程序版本会有Bug,可能导致扩展的配置⽆法更新,如果在执
⾏./buildconf时 报错,可以更具出错信息安装合适版本的autoconf⼯具。
./configure --help # 查看可⽤参数
为了尽快得到可以测试的环境,我们仅编译⼀个最精简的PHP。通过执⾏ ./configure --disable-all来进
⾏配置。 以后如果需要其他功能可以重新编译。如果configure命令出现错误,可能是缺少PHP所依赖的
库,各个系统的环境可能不⼀样。 出现错误可根据出错信息上⽹搜索。 直到完成configure。configure完
成后我们就可以开始编译了。
./configure --disable-all
make
TIPI:深⼊理解PHP内核 RELEASE_2012-04-04_V0.7.3
在*nix下编译过程序的读者应该都熟悉经典的configure make,make install吧。执⾏make之后是否需
要make install就取决于你了。 如果install的话最好在configure的时候是⽤prefix参数指定安装⽬录, 不建
议安装到系统⽬录, 避免和系统原有的PHP版本冲突。 在make 完以后,在sapi/cli⽬录⾥就已经有了php
的可以执⾏⽂件. 执⾏⼀下命令:
./sapi/cli/php -v
-v参数表⽰输出版本号,如果命令执⾏完后看到输出php版本信息则说明编译成功。 如果是make
install的话可以执⾏$prefix/bin/php这个路径的php。 当然如果是安装在系统⽬录或者你的prefix⽬录在
$PATH环境变量⾥的话,直接执⾏php就⾏了。
在只进⾏make⽽不make install时,只是编译为可执⾏⼆进制⽂件,所以在终端下执
⾏的php-cli所在路径就是php-src/sapi/cli/php。
后续的学习中可能会需要重复configure make 或者 make && make install 这⼏个步骤。
推荐推荐书籍和参考籍和参考
linuxsir.org的make介绍 http://www.linuxsir.org/main/doc/gnumake/GNUmake_v3.80-
zh_CN_html/index.html
《Autotools A Practioner's Guide》
第⼆第⼆节 源源码结构、、阅读代代码⽅法⽅法
PHP源源码⽬⽬录结构
俗话讲:重剑⽆锋,⼤巧不⼯。PHP的源码在结构上⾮常清晰。下⾯先简单介绍⼀下PHP源码的⽬录
结构。
根⽬根⽬录: / 这个⽬录包含的东⻄⽐较多,主要包含⼀些说明⽂件以及设计⽅案。 其实项⽬中的这些
README⽂件是⾮常值得阅读的例如:
/README.PHP4-TO-PHP5-THIN-CHANGES 这个⽂件就详细列举了PHP4和PHP5的⼀些差
异。
还有有⼀个⽐较重要的⽂件/CODING_STANDARDS,如果要想写PHP扩展的话,这个⽂件⼀
定要阅读⼀下, 不管你个⼈的代码风格是什么样,怎么样使⽤缩进和花括号,既然来到了这
样⼀个团体⾥就应该去适应这样的规范,这样在阅读代码或者别⼈阅读你的 代码是都会更轻
松。
build 顾名思义,这⾥主要放置⼀些和源码编译相关的⼀些⽂件,⽐如开始构建之前的buildconf脚本
等⽂件,还有⼀些检查环境的脚本等。
ext 官⽅扩展⽬录,包括了绝⼤多数PHP的函数的定义和实现,如array系列,pdo系列,spl系列等
函数的实现,都在这个⽬录中。个⼈写的扩展在测试时也可以放到这个⽬录,⽅便测试和调试。
main 这⾥存放的就是PHP最为核⼼的⽂件了,主要实现PHP的基本设施,这⾥和Zend引擎不⼀
样,Zend引擎主要实现语⾔最核⼼的语⾔运⾏环境。
Zend Zend引擎的实现⽬录,⽐如脚本的词法语法解析,opcode的执⾏以及扩展机制的实现等等。
TIPI:深⼊理解PHP内核 RELEASE_2012-04-04_V0.7.3