201411-07 PHP内核探索 —— 从SAPI接口开始 SAPI:ServerApplicationProgrammingInterface服务器端应用编程端口。研究过PHP架构的同学应该知道这个东东的重要性,它提供了一个接口,使得PHP可以和其他应用进行交互数据。本文不会详细介绍每个PHP的SAPI,只是针对最简单的CGISAPI,来说明SAPI的机制。我们先来看看PHP的架构图:SAPI指的是PHP具体应用的编程接口,就像PC一样,无论安装哪些操作系统,只要满足了PC的接口规范都可以在PC上正常运行,PHP脚本要执行有... 继续阅读 >
201411-07 PHP内核探索 —— 一次请求的开始与结束:MINIT和RINIT、RSHUTDOWN和MSHUTDOWN PHP开始执行以后会经过两个主要的阶段:处理请求之前的开始阶段请求之后的结束阶段开始阶段有两个过程:第一个过程是模块初始化阶段(MINIT),在整个SAPI生命周期内(例如Apache启动以后的整个生命周期内或者命令行程序整个执行过程中),该过程只进行一次。第二个过程是模块激活阶段(RINIT),该过程发生在请求阶段,例如通过url请求某个页面,则在每次请求之前都会进行模块激活(RINIT请求开始)。例如PHP注册了一... 继续阅读 >
201411-07 PHP内核探索 —— 一次请求生命周期:PHP的启动与关闭 我们从未手动开启过PHP的相关进程,它是随着Apache的启动而运行的。PHP通过mod_php5.so模块和Apache相连(具体说来是SAPI,即服务器应用程序编程接口)。PHP总共有三个模块:内核、Zend引擎、以及扩展层。PHP内核用来处理请求、文件流、错误处理等相关操作;Zend引擎(ZE)用以将源文件转换成机器语言,然后在虚拟机上运行它;扩展层是一组函数、类库和流,PHP使用它们来执行一些特定的操作。比如,我们需要mysql扩展来连接... 继续阅读 >
201411-07 PHP内核探索 —— 单进程和多进程/线程SAPI生命周期 单进程SAPI生命周期CLI/CGI模式的PHP属于单进程的SAPI模式。这类的请求在处理一次请求后就关闭。也就是只会经过如下几个环节:开始-请求开始-请求关闭-结束SAPI接口实现就完成了其生命周期。单进程多请求则如下图所示:多进程SAPI生命周期通常PHP是编译为apache的一个模块来处理PHP请求。Apache一般会采用多进程模式,Apache启动后会fork出多个子进程,每个进程的内存空间独立,每个子进程都会经过开始和结束环节... 继续阅读 >
201411-07 PHP内核探索 —— Zend引擎:Zend引擎是PHP实现的核心 相信很多人都听说过ZendEngine这个名词,也有很多人知道ZendEngine就是PHP语言的核心,但若要问一句:ZendEngine到底存在于何处?或者说,ZendEngine究竟是在什么时候怎么发挥作用让PHP源码输出我们想要的东西的?Zend引擎是PHP实现的核心,提供了语言实现上的基础设施。例如:PHP的语法实现,脚本的编译运行环境,扩展机制以及内存管理等,当然这里的PHP指的是官方的PHP实现(除了官方的实现,目前比较知名的有f... 继续阅读 >
201411-07 PHP内核探索 —— 再次探讨SAPI 在PHP的生命周期的各个阶段,一些与服务相关的操作都是通过SAPI接口实现。这些内置实现的物理位置在PHP源码的SAPI目录。这个目录存放了PHP对各个服务器抽象层的代码,例如命令行程序的实现,Apache的mod_php5模块实现以及fastcgi的实现等等。在各个服务器抽象层之间遵守着相同的约定,这里我们称之为SAPI接口。每个SAPI实现都是一个_sapi_module_struct结构体变量。(SAPI接口)。在PHP的源码中,当需要调用服务器相关信息时... 继续阅读 >
201411-07 PHP内核探索 —— Apache模块介绍 Apache概述Apache是目前世界上使用最为广泛的一种WebServer,它以跨平台、高效和稳定而闻名。按照去年官方统计的数据,Apache服务器的装机量占该市场60%以上的份额。尤其是在X(Unix/Linux)平台上,Apache是最常见的选择。其它的WebServer产品,比如IIS,只能运行在Windows平台上,是基于微软.Net架构技术的不二选择。Apache支持许多特性,大部分通过模块扩展实现。常见的模块包括mod_auth(权限验证)、mod_ssl(SSL和TLS支... 继续阅读 >
201411-07 PHP内核探索 —— 通过mod_php5支持PHP Apache对PHP的支持是通过Apache的模块mod_php5来支持的。如果希望Apache支持PHP的话,在./configure步骤需要指定--with-apxs2=/usr/local/apache2/bin/apxs 表示告诉编译器通过Apache的mod_php5/apxs来提供对PHP5的解析。在最后一步makeinstall的时候我们会看到将动态链接库libphp5.so(Apache模块)拷贝到apache2的安装目录的modules目录下,并且还需要在httpd.conf配置文件中添加LoadModule语句来动态将libphp5.so 模块加载进... 继续阅读 >
201411-07 PHP内核探索 —— Apache运行与钩子函数 Apache是目前世界上使用最为广泛的一种WebServer,它以跨平台、高效和稳定而闻名。按照去年官方统计的数据,Apache服务器的装机量占该市场60%以上的份额。尤其是在X(Unix/Linux)平台上,Apache是最常见的选择。其它的WebServer产品,比如IIS,只能运行在Windows平台上,是基于微软.Net架构技术的不二选择。Apache并不是没有缺点,它最为诟病的一点就是变得越来越重,被普遍认为是重量级的WebServer。所以,近年来又涌现出了很... 继续阅读 >
201411-07 PHP内核探索 —— 嵌入式PHP:类似CLI 从PHP源码目录结构的介绍以及PHP生命周期可知:嵌入式PHP类似CLI,也是SAPI接口的另一种实现。一般情况下,它的一个请求的生命周期也会和其它的SAPI一样:模块初始化=>请求初始化=>处理请求=>关闭请求=>关闭模块。当然,这只是理想情况。因为特定的应用由自己特殊的需求,只是在处理PHP脚本这个环节基本一致。对于嵌入式PHP或许我们了解比较少,或者说根本用不到,甚至在网上相关的资料也不多,例如很多游戏中使用Lua语言作为... 继续阅读 >
201411-07 PHP内核探索 —— PHP的FastCGI:FastCGI的整个工作流程 CGI全称是“通用网关接口”(CommonGatewayInterface),它可以让一个客户端,从网页浏览器向执行在Web服务器上的程序请求数据。CGI描述了客户端和这个程序之间传输数据的一种标准。CGI的一个目的是要独立于任何语言的,所以CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。如php,perl,tcl等。FastCGI是Web服务器和处理程序之间通信的一种协议,是CGI的一种改进方案,FastCGI像是一个常驻(long-li... 继续阅读 >
201411-07 PHP内核探索 —— 如何执行PHP脚本:Zend引擎是如何解释PHP脚本的 前面介绍了PHP的生命周期,PHP的SAPI,SAPI处于PHP整个架构较上层,而真正脚本的执行主要由Zend引擎来完成,这一小节我们介绍PHP脚本的执行。目前编程语言可以分为两大类:第一类是像C/C++,.NET,Java之类的编译型语言,它们的共性是:运行之前必须对源代码进行编译,然后运行编译后的目标文件。第二类比如PHP,Javascript,Ruby,Python这些解释型语言,他们都无需经过编译即可“运行”。虽然可以理解为直接运行,... 继续阅读 >
201411-07 PHP内核探索 —— PHP脚本的执行细节:PHP、C、汇编、机器码 众所周知,计算机的CPU只能执行二进制的机器码,每种CPU都有对应的汇编语言,汇编语言编译器将汇编语言翻译成二进制的机器语言,然后CPU开始执行这些机器码。汇编语言作为机器语言与程序设计者之间的一个层,给我们带来了很多方便,程序员不需要用晦涩的01数字来书写程序,当然人们并不满足这样的一个进步,于是在汇编语言之上又多了一个层——C语言,C语言更贴近人类熟悉的“自然语言”,程序设计者可以通过C语言编译器将C源代码... 继续阅读 >
201411-07 PHP内核探索 —— 操作码OpCode:计算机最终是执行这些OpCode 运行一段PHP代码主要有两个阶段:编译和执行。当然编译过程中还包括词法分析语法分析不同阶段和细节,这里我们将其作为一个整体。在这两个阶段之间,PHP代码会被编译成opcode,可以将其认为是引擎的一个中间语言,编辑阶段把PHP源码生成opcode,然后在执行阶段执行这些opcode。这篇文章将简单的介绍opcode。PHP代码编译之后会生成许多的op,每一个op都是一个zend_op类型的c变量。相关的定义可以在{PHPSRC}/Zend/zend_compile.h中... 继续阅读 >
201411-07 PHP内核探索 —— PHP里的opcode:Zend虚拟机中的指令 opcode是计算机指令中的一部分,用于指定要执行的操作,指令的格式和规范由处理器的指令规范指定。除了指令本身以外通常还有指令所需要的操作数,可能有的指令不需要显式的操作数。这些操作数可能是寄存器中的值,堆栈中的值,某块内存的值或者IO端口中的值等等。通常opcode还有另一种称谓:字节码(bytecodes)。例如Java虚拟机(JVM),.NET的通用中间语言(CIL:CommonIntermeditateLanguage)等等。PHP中的opcode则属于前面... 继续阅读 >
201411-07 PHP内核探索 —— 解释器的执行过程:引擎是如何执行PHP代码的 这里将介绍引擎内部执行一个PHP脚本的流程,以CLISAPI为例子来对流程中核心的部分做简单介绍,省去一些初始化及清理操作。CLI(CommandLineInterface)即PHP的命令行模式,现在此SAPI是默认安装的,我们在服务器上安装完PHP之后,一般会生成一个可执行文件,假设此文件为/usr/local/bin/php ,那么我们在SHELL下可以用以下命令来执行一个PHP脚本:/usr/local/bin/php-ftest.php这个命令将执行当前目录下的test.php脚本,我... 继续阅读 >