Entries tagged with “commentary on php”.


源码分析,首先得看源码。记事本可以看,EditPlus 也可以看,但显然具有语法着色功能的 EditPlus 要比记事本爽。更显然,M$ 的 Visual C++ 比 EditPlus 还要爽。:D 因此我推荐的第一款神兵就是 M$ Visual C++(Sorry, Linuxer~)。既然用了 Visual C++ 那么有一款它的插件我们不得不提:Visual Assist X,还没有她的朋友尽快拥有她吧~

OK,现在源码是可以看了,而且是很舒服地在看,但有时我们还想实地进行单步调试以一窥究竟。要调试自然得先编译。很不幸,PHP 在 Windows 环境下的编译和调试并不像想象中的那么简单。我们至少得比在 xNix 环境下多做一下几个步骤:

  1. 下载 PHP 使用的 DNS 解析器的源代码(http://www.php.net/extra/bindlib_w32.zip)并将其编译输出一个名为 resolv.lib 的库文件。
  2. 下载 win32 编译工具 http://www.php.net/extra/win32build.zip ,解压至某一目录(假定为 $work)。在 $work\lib 目录里面也有个 resolv.lib,我们把步骤 1 产生的 resolv.lib 复制到这个目录,覆盖之。
  3. 设置编译环境。把 $Work\bin 添加到系统 PATH 环境变量和 Visual C++ 的 Executable files 目录;把 $work\lib 添加到 Library files 目录;把 $Work\include 添加到 Include files 目录。
  4. 下载 PHP 源文件并解压至 $work 。
  5. 整理 PHP 的项目工程文件。PHP 4.x 的 VC 工程文件($PHP\win32\php4ts*.dsw)是当时一直在维护的,因此可以直接拿来就用。PHP 5.x 增加了一种新的基于命令行的类 Unix 编译系统,使得编译 PHP 更为简单。于是相应的工程文件 php5ts*.dsw 便不再被 PHP 团队维护,也不能直接使用编译 PHP 5 了。但我们恰恰不想单纯的编译,我们想的是在 Visual C++ 里面进行编译然后下断点单步调试,因此我们就需要命令行编译系统的编译流程重建这个项目工程文件(可能还需要对某些文件做些必要的改动)。

为方便大家不做重复性劳动,我把我现在用的 PHP 调试环境打包发上来,大家下载后直接解压到某一目录即可。所需另外做的也只是根据你解压的目录设置一下编译的环境变量(见步骤 3),之后就可直接进入 $work\win32 打开 php5ts.dsw。

这里是该 PHP win32 VC 编译项目包。

工程文件说明:这其实是个“精简版”PHP 的工程文件,里面的 PHP 是 php 5.2.8 的源码,但只包含 date、filter、pcre、reflection、session、standard、tokenizer 这几个内建扩展。另外 php5apache2 的 sapi 不能编译,要想编译它得再去下一份 Apache 2 的源码。除此之外还删除了大部分的测试脚本。

最后再说一下分析 PHP 源代码所需要一些基础知识。首先当然得有一定的 C 语言基础。在最后分析 Zend Engine 时可能还需要一些编译器方面知识,最好能看懂一些 lex&yacc 的语法文件(PHP 采用的是 flex 和 bison,但在语法层面相差无几)。最后是能有一定的调试技术。包括在 VC++ 环境下的有源码调试技术和无源码的二进制代码调试技术(这种情况下我一般用OllyDbg)。其中 C 语言基础是必须的,而后面的两种知识/技术则可有可无,但有的话可以达到事半功倍之效。

目前在 PHP 社区尤其是国内的 PHP 社区对 PHP 内核这方面讨论的比较少。我平时常看一些 PHP 源码,对 PHP 的运行机制算是有一些认识吧,因此我打算写一些这方面的文章,算是抛砖引玉。最终目标我希望可以做成一个关于 PHP 内核的中文百科全书。应该说这是一个不算太小的工程,依我个人之力几乎不可能完成。更何况老子曾经曰过:“知者不言,言者不知”,相信潜在水下面的大牛(水牛?^_^)还有 N 多。所以希望大家群策群力,共同完成这个项目。

整个项目我初步打算以 PHP 5.2.x 的源码为研究对象,侧重于对 Zend Engine 的表述,兼顾一些 SAPI 层。下面是我列出的一份清单,大家看看还有没有什么遗漏或者内容编排不合理之处。请诸位畅所欲言,有啥说啥,即使跑题也没关系~ 😀

    PHP 源代码分析 V0.0.1

    第一章 构建系统

  1. 准备工具、库及需要具备的基础知识;
  2. 如何编译不同平台的版本?编译时的各个选项是什么含义?源码的目录结构。
  3. 如何创建一个 PHP 扩展/模块?如何创建一个 Zend 扩展?
  4. 如何调试 PHP?如何调试 PHP/Zend 扩展?
    第二章 PHP 与 SAPI 的生命周期

  1. 脚本的运行周期,一切从 main() 开始;
  2. 模块/脚本的起始与终止函数;
  3. PHP SAPI 协议;
  4. 嵌入式 PHP 设计。
    第三章 内存管理

  1. Zend 的内存管理器框架;
  2. 内存申请与释放流程,垃圾回收;
  3. 持久化(persistence)
    第四章 线程安全

  1. 为何会有这个问题?Zend Engine 是如何解决的?
  2. 我是否该启用 ZTS?各有什么优缺点?
  3. 如何构建一个 ZTS 的程序/扩展?
    第五章 变量与常量

  1. PHP 中的数据类型。
  2. 变量、常量与静态变量。
  3. 引用计数机制;
  4. 资源的创建与回收;
  5. 未来字符串的 UNICODE 支持、JIT 支持。
    第六章 函数

  1. 函数的内部布局;
  2. 函数的定义;
  3. 如何获取函数的参数、可选参数、参数默认值;
  4. 函数的返回值;
    第七章 类与对象

  1. 类的内部布局(属性、方法);
  2. 构造函数与析构函数;
  3. 类的继承与转换(up casting 与 down casting);
  4. 接口(轻量级的类),微观上与类的差别;
  5. 类之间的 up casting 和 down casting。
  6. stdClass。
    第八章 错误与异常

  1. 什么是错误、什么是异常。两者的区别;
  2. 如何创建和抛出异常;
  3. try/catch 的设计与实现;
    第九章 流(Streams)支持

  1. 这方面我接触较少,内容待定;
    第十章 虚拟机

  1. 脚本编译机制(词法分析、语法分析);
  2. 脚本的执行机制(CALL|SWITCH|GOTO);
  3. 各个符号表的作用;
  4. 开发 OPCode 缓存器;
  5. 开发 PHP 调试器;
    附录

  1. 完整的 PHP API、Zend API 以及宏(Micro)参考(长期工程)
  2. Zend Engine 1 的主要特性,与 Zend Engine 2的主要差别;
  3. Zend Engine 3 的主要特性,与 Zend Engine 2的主要差别;
  4. 相关资源
  • 项目发起:Ben (ben.yan at msn dot com
  • 项目参与:Ben (ben.yan at msn dot com,http://www.yAnbiN.org
  • 项目启动:2007/06/09 (希望可以在明年奥运会开幕前完成 :D)
  • 项目进度:
    1. 2007/06/09 项目启动,讨论项目规划;
    2. 2007/xx/xx 待续……