深入理解PHP内核

Thinking In PHP Internal

第二章 用户代码的执行

不识庐山真面目,只缘身在此山中。

PHP做为一种优秀的脚本语言,在当前的互联网应用中可谓风光无限。 从简单的“Hello World!”到各种框架开发,架构设计,性能优化,到编写PHP扩展, PHP编程中涉及的知识结构和跨度蔚为可观。 从这个角度上来看,学会PHP编程的语法可能并不困难, 但如果想真正用好PHP,在不同的场景下发挥PHP最大的性能和效用, 对PHP的理解到达熟悉和精通的程度,就不得不去了解PHP语言的实现, 进一步理解PHP语法的本质,这确实是一件需要更多的精力和时间的事情。

PHP语言经过许多人多年的淬炼,性能不断优化,支持的语法现象与各种特性也越来越多。 导致PHP内核的代码中,涉及知识面比较广泛,具体实现也非常复杂, 从脚本的编译解析到执行以及和Web服务器等的配合,内存管理,语法实现等等。 为了不过早陷入细节的沼泽,我们先从整体上来接触PHP的实现, 先对PHP的整体结构,生命周期,PHP与其它容器(如Apache)的交互, PHP的整个执行过程等进行一个大概的了解,从而有一个整体的概念。

关于PHP是如何一步步从一个朴素的想法发展到今天的模样,可以了解一下PHP的历史: http://en.wikipedia.org/wiki/PHP

从宏观上来看,PHP内核的实现与世界上绝大多数的程序一样,接收输入数据, 做相应处理然后输出(返回)结果。 我们编写的代码就是PHP接收的输入数据,PHP内核对我们编写的代码进行解释和运算, 最后返回相应的运算结果。 然而,PHP与我们自己平时写的一般的C程序有所不同的是, 我们的程序一般用来解决某个具体问题, 而PHP本身实现了把用户的逻辑“翻译”为机器语言来执行的功能, 这也是各种编译语言与承载具体业务逻辑的程序代码的一个明显区别。 于是PHP就多出一个把用户代码“翻译”成具体操作的步骤:词法分析、语法分析

当用户代码输入给PHP内核去执行的时候, PHP内核会对PHP代码进行词法分析和语法分析, 词法分析是把PHP代码分割成一个个的“单元”(TOKEN), 语法分析则将这些“单元”转化为Zend Engine可执行的操作。 然后PHP内部的Zend Engine对这些操作进行顺次的执行。 Zend Engine是PHP内核的核心部分,负责最终操作的执行和结果的返回, 可以理解成为PHP内核中的“发动机”。

于是PHP代码的执行过程可以简单描述为下图:

图2.1 单进程SAPI生命周期
图2.1 单进程SAPI生命周期

接下来,本章会对图中的每一部分展开详细的讨论,主要包括以下内容:

  1. PHP内部的生命周期
  2. SAPI接口
  3. 词法分析与语法分析
  4. 什么是Opcodes