资讯专栏INFORMATION COLUMN

如何学习 PHP 源码 - 从编译开始

hss01248 / 1001人阅读

摘要:上这两天有个好玩儿的问题,大概就是有人想知道如何学习源码,可是这种事情不是应该自己去发掘的吗上面是玩笑话,现在我也说说如何学习解释器的源码。在源码根中已经准备了两份配置文件的模板和。

PHP Mailing Lists 上这两天有个好玩儿的问题:Introduction to the PHP source code,大概就是有人想知道如何学习 PHP 源码,可是这种事情不是应该自己去发掘的吗?

上面是玩笑话,现在我也说说如何学习 PHP 解释器的源码。

首选你要知道的是 PHP 解释器源码的 github 地址:https://github.com/php/php-src ,话说回来还有人不知道吗?这里有几乎所有 PHP 的代码提交记录、pull requests 和一些 issue 等。

创建编译脚本或者发布包

从 Branch 中选择一个版本 tag,和每次 PHP 发布出来的版本就是一致的。也许你会发现你想编译的的时候缺找不到 configure 文件,但是有 configure.in 文件。这时候需要先执行的是 buildconf(如果是在 Windows 下面可以执行 buildconf.bat,不过我从来没有尝试过在 Windows 下面编译 PHP,所以具体的步骤我就不清楚了)。buildconf 本身是个简单的 shell 脚本,你可以用记事本打开看看它(最终的执行文件在 build 目录里,这个目录里有一些与编译有关的文件)。

这里面涉及到一个系列的编译工具:Autotools。如果你有兴趣,可以简单的了解一下,没有兴趣的话也不用多考虑,因为这些工具绝大多数 Linux 系统上都是已经存在的。

如果你想将 Github 上的 PHP 源码做成一个可发布的源码包,你可以看看 makedist 这个文件,它也是一个 shell 脚本(实际上源码里几乎所有跟编译相关的脚本都是 shell 脚本)。但是如果想直接执行者这个脚本,你可能会收到缺少以下组件的提示:re2cBison。仔细看 makedist 的文件,里面有调用 genfiles 这个脚本的语句,上面两个工具就是在 genfiles 的脚本里被调用的。

re2c 和 Bison 分别是 PHP 用到的词法解析器和语法分析器。在 genfiles 这个文件中可以看到它们的调用其实是在 Makefile.frag 中写着,分别通过 zend_language_scanner.lzend_language_parser.y 生成相应的 C 语言文件(这个应该很多地方都有提到过)。

编译解释器并初始化

到了编译环节,编译之前需要先通过 configure 文件生成 Makefile 然后执行 make,所以 gcc 自然是必不可少的。configure 文件本身也是一个 shell 脚本,你也可以简单阅读一下它的内容。不过既然它是由 autoconfconfigure.in 中生成的,也许直接查看 configure.in 会更轻松一些。

到这里总结一下就是:抛开一些核心扩展额依赖(比如 xml,ssl 等),编译 PHP 的先决条件是机器上有 Autotools 的工具(automake,autoconf 等),需要安装 re2c 和 Bison,当然还有编译工具(gcc)。

也许大家都知道,使用 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-developmentphp.ini-production。显然是分别用于开发环境和生产环境的,将其中一个复制到配置文件目录并重命名为 php.ini 即可(如果你不知道配置文件的目录在哪里,可以使用 php --ini 命令查看)。然后也可以根据你的需要修改它。

至于 php-fpm 的控制脚本,源码中本身也是有提供的,在 sapi/fpm 目录下。这个目录下的几个文件中有 php-fpm 配置文件的模板,也有稍微修改即可放到服务器 /etc/init.d 目录下用于控制 php-fpm 的 startstoprestartreload 动作的脚本,现在的版本中也提供了用于 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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/22282.html

相关文章

  • PHP程序员学习路线

    摘要:第一阶段基础阶段基础程序员重点把搞熟练核心是安装配置基本操作目标能够完成基本的系统安装,简单配置维护能够做基本的简单系统的开发能够在中型系统中支持某个功能模块的开发。本项不做重点学习,除非对前端有兴趣。 第一阶段:基础阶段(基础PHP程序员) 重点:把LNMP搞熟练(核心是安装配置基本操作) 目标:能够完成基本的LNMP系统安装,简单配置维护;能够做基本的简单系统的PHP开发;能够在P...

    genedna 评论0 收藏0
  • 如何编写一个独立的 PHP 扩展(译)

    摘要:独立的扩展可以独立于源码之外进行分发。定义一个新扩展我们给示例扩展命名为。对于一个独立扩展来说,你只需要做一些宏调用即可。通过以上的步骤,你已经有了一个独立的扩展了。 本文翻译自 PHP 源码中的 README.SELF-CONTAINED-EXTENSIONS。文中标记了 注 的内容均为自己添加。内容有点老,也挺啰嗦,没讲什么深入的内容,但是可以作为入门学习参考。 独立的 PHP 扩...

    JerryZou 评论0 收藏0
  • [PHP源码阅读]empty和isset函数

    摘要:函数使用格式判断变量是否为空。对于,如果变量被如的函数设为,则函数会返回。,到分支,,返回数组元素的数量,为空,因此为,,,因此返回。 近日被问到PHP中empty和isset函数时怎么判断变量的,刚开始我是一脸懵逼的,因为我自己也只是一知半解,为了弄懂其真正的原理,赶紧翻开源码研究研究。经过分析可发现两个函数调用的都是同一个函数,因此本文将对两个函数一起分析。 我在github有对P...

    Pink 评论0 收藏0
  • Laravel 学习笔记之 Query Builder 源码解析(中)

    说明:本篇主要学习数据库连接阶段和编译SQL语句部分相关源码。实际上,上篇已经聊到Query Builder通过连接工厂类ConnectionFactory构造出了MySqlConnection实例(假设驱动driver是mysql),在该MySqlConnection中主要有三件利器:IlluminateDatabaseMysqlConnector;IlluminateDatabaseQuery...

    zhou_you 评论0 收藏0

发表评论

0条评论

hss01248

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<