PHP Mailing Lists 上这两天有个好玩儿的问题:Introduction to the PHP source code,大概就是有人想知道如何学习 PHP 源码,但是这种事情不是应该本身去发掘的吗?php
上面是玩笑话,如今我也说说如何学习 PHP 解释器的源码。html
首选你要知道的是 PHP 解释器源码的 github 地址:https://github.com/php/php-src ,话说回来还有人不知道吗?这里有几乎全部 PHP 的代码提交记录、pull requests 和一些 issue 等。node
从 Branch 中选择一个版本 tag,和每次 PHP 发布出来的版本就是一致的。也许你会发现你想编译的的时候缺找不到 configure
文件,可是有 configure.in
文件。这时候须要先执行的是 buildconf
(若是是在 Windows 下面能够执行 buildconf.bat
,不过我历来没有尝试过在 Windows 下面编译 PHP,因此具体的步骤我就不清楚了)。buildconf 自己是个简单的 shell 脚本,你能够用记事本打开看看它(最终的执行文件在 build
目录里,这个目录里有一些与编译有关的文件)。git
这里面涉及到一个系列的编译工具:Autotools。若是你有兴趣,能够简单的了解一下,没有兴趣的话也不用多考虑,由于这些工具绝大多数 Linux 系统上都是已经存在的。github
若是你想将 Github 上的 PHP 源码作成一个可发布的源码包,你能够看看 makedist
这个文件,它也是一个 shell 脚本(实际上源码里几乎全部跟编译相关的脚本都是 shell 脚本)。可是若是想直接执行者这个脚本,你可能会收到缺乏如下组件的提示:re2c
和 Bison
。仔细看 makedist 的文件,里面有调用 genfiles
这个脚本的语句,上面两个工具就是在 genfiles 的脚本里被调用的。shell
re2c 和 Bison 分别是 PHP 用到的词法解析器和语法分析器。在 genfiles 这个文件中能够看到它们的调用实际上是在 Makefile.frag
中写着,分别经过 zend_language_scanner.l
和 zend_language_parser.y
生成相应的 C 语言文件(这个应该不少地方都有提到过)。api
到了编译环节,编译以前须要先经过 configure
文件生成 Makefile 而后执行 make
,因此 gcc
天然是必不可少的。configure 文件自己也是一个 shell 脚本,你也能够简单阅读一下它的内容。不过既然它是由 autoconf
从 configure.in
中生成的,也许直接查看 configure.in 会更轻松一些。服务器
到这里总结一下就是:抛开一些核心扩展额依赖(好比 xml,ssl 等),编译 PHP 的先决条件是机器上有 Autotools 的工具(automake,autoconf 等),须要安装 re2c 和 Bison,固然还有编译工具(gcc)。php-fpm
也许你们都知道,使用 configure
生成 Makefile 的时候能够经过 --prefix
参数指定目录,同时也能够选择编译哪些核心模块。至于哪些模块会被默认集成而哪些不会,这些自己是写在每一个扩展的 config.m4
(也有几个是被命名为 config0.m4 或 config9.m4)文件里的的,全都经过一些 --enable
、--disable
、--with
和 --without
的选项来控制。工具
编译的也与你采用的 Web 服务器有关,这涉及到你须要使用哪一个 sapi
,若是是 Apache,也许须要指定 --with-apxs2
的参数,若是是 Nginx,php-fpm
在默认条件下是会被编译的,但能够指定 php-fpm 的执行组和用户,不过这个是能够在编译完成后在配置中修改的。
编译完成以后还有一些事情须要考虑,最基本的问题是 PHP 的配置文件的问题,还有一个是若是使用的是 php-fpm,如何更便捷的控制它的启动、中止以及重启等。
在 PHP 源码根中已经准备了两份配置文件的模板:php.ini-development
和 php.ini-production
。显然是分别用于开发环境和生产环境的,将其中一个复制到配置文件目录并重命名为 php.ini
便可(若是你不知道配置文件的目录在哪里,可使用 php --ini
命令查看)。而后也能够根据你的须要修改它。
至于 php-fpm 的控制脚本,源码中自己也是有提供的,在 sapi/fpm
目录下。这个目录下的几个文件中有 php-fpm 配置文件的模板,也有稍微修改便可放到服务器 /etc/init.d
目录下用于控制 php-fpm 的 start
、stop
、restart
和 reload
动做的脚本,如今的版本中也提供了用于 systemd
的 service 文件。
若是 PHP 编译完成以后,发现还须要一些没有编译进去的核心扩展或者第三方扩展,你能够单独编译它们。
扩展编译的整个过程一共四句命令:
phpize
./configure
make
make install
phpize
命令是用来准备 PHP 扩展库的编译环境的。在执行 phpize
的时候,若是有多个版本的 PHP,用哪一个就要选哪一个。这个命令和编译后的 php 的二进制文件在同一个目录中,也是一个 shell 脚本。
执行 configure
的时候,若是当前 $PATH
中找不到 php-config
或者有多个版本的 PHP 时,也须要经过 --with-php-config
的指令来指定 php-config 的目录。php-config 是一个用于获取所安装的 PHP 配置的信息,它也同样是和 php 的二进制文件在同一个目录的 shell 脚本。
phpize 和 php-config 的源码生成文件都是在 scripts 目录下。
全部工做完成以后,就能够愉快的使用你本身定制的 PHP 了。
原文地址:http://0x1.im