PHP代码的执行

先看下PHP的结构图:php

1)Zend Enginehtml

Zend引擎是PHP实现的核心,提供了语言实现上的基础设施。例如:PHP的语法实现,脚本的编译运行环境, 扩展机制以及内存管理等。web

2)Extensionsapache

围绕着zend引擎,Extensions经过组件式的方式提供各类基础服务,咱们常见的各类内置函数(如MySQL系列)、标准库等都是经过Extension来实现,用户也能够根据须要实现本身的extension以达到功能扩展、性能优化等目的。编程

3)SAPIsegmentfault

SAPI(Server Application Programming Interface)指的是PHP具体应用的编程接口。就像PC同样,不管安装哪些操做系统,只要知足了PC的接口规范均可以在PC上正常运行。浏览器

4)架构思想缓存

若是php是一辆车,那么车的框架就是php自己,Zend是车的引擎(发动机),Ext下面的各类组件就是车的轮子,SAPI能够看作是公路,车能够跑在不一样类型的公路上,而一次php程序的执行就是汽车跑在公路上。所以,咱们须要:性能优异的引擎+合适的车轮+正确的跑道。性能优化

 

1、Apache

Apache是Apache软件基金会的一个开放源代码的Web服务器,Apache支持许多特性,大部分经过模块扩展实现。服务器

常见的模块包括mod_auth(权限验证)、mod_ssl(SSL和TLS支持) mod_rewrite(URL重写)等。

下图为Apache的逻辑构成以及与操做系统的关系:

 

1)Apache的mod_php5模块

当PHP须要在Apache服务器下运行时,能够用mod_php5模块的形式集成。

此时mod_php5模块的做用是接收Apache传递过来的PHP文件请求,并处理这些请求, 而后将处理后的结果返回给Apache。

 

2)Apache的运行过程

Apache的运行分为启动阶段和运行阶段。

在运行阶段,Apache主要工做是处理用户的服务请求。

Apache对HTTP的请求能够分为链接、处理和断开链接三个大的阶段。同时也能够分为11个小的阶段:

Post-Read-Request,URI Translation,Header Parsing,Access Control,Authentication,

Authorization,MIME Type Checking,FixUp,Response,Logging,CleanUp。

 

3)Apache Hook机制

模块能够在Apache的任何一个处理阶段中挂接(Hook)上本身的处理函数,从而参与Apache的请求处理过程。

 

2、FastCGI

1)CGI

  CGI全称是“通用网关接口”(Common Gateway Interface),描述了客户端和服务器程序之间传输数据的一种标准。它可让一个客户端,从网页浏览器向执行在Web服务器上的程序请求数据。CGI用来沟通程序(如PHP, Python, Java)和Web服务器(Apache2, Nginx),理论上任何语言编写的程序均可以经过CGI来提供Web服务。

  好比如今请求的是“index.php”,根据配置文件,Apache知道这个不是静态文件,须要去找PHP解析器来处理,那么它会把这个请求简单处理后交给PHP解析器。Apache会传url、查询字符串、POST数据、HTTP header等,而CGI就是规定要传哪些数据、以什么样的格式传递给后方处理这个请求的协议。

  当web服务器收到“index.php”这个请求后,会启动对应的CGI程序,这里就是PHP的解析器。接下来PHP解析器会解析php.ini、载入所有扩展并初始化所有数据结构,而后处理请求,再以CGI规定的格式返回处理后的结果,退出进程,web服务器再把结果返回给浏览器。

 

2)FastCGI

  CGI程序存在性能问题,每次请求都会重复“PHP解析器会解析php.ini、载入所有扩展并初始化所有数据结构”这些步骤。

  FastCGI是CGI的一种改进方案。FastCGI像是一个常驻(long-live)型的CGI, 它能够一直执行,在请求到达时不会花费时间去fork一个进程来处理(这是CGI最为人诟病的fork-and-execute模式)。

FastCGI工做流程的通俗版本以下:

1. Fastcgi会先启一个master,解析配置文件,初始化执行环境,而后再启动多个worker。

2. 当请求过来时,master会传递给一个worker,而后当即能够接受下一个请求。这样就避免了重复的劳动,效率天然是高。

3. 当worker不够用时,master能够根据配置预先启动几个worker等着。

4. 当空闲worker太多时,也会停掉一些,这样就提升了性能,也节约了资源。

FastCGI工做流程的专业版本以下:

1. Web Server启动时载入FastCGI进程管理器(IIS ISAPI或Apache Module)

2. FastCGI进程管理器自身初始化,启动多个CGI解释器进程(可见多个php-cgi)并等待来自Web Server的链接。

3. 当客户端请求到达Web Server时,FastCGI进程管理器选择并链接到一个CGI解释器。Web server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi。

4. FastCGI子进程完成处理后将标准输出和错误信息从同一链接返回Web Server。当FastCGI子进程关闭链接时, 请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在Web Server中)的下一个链接。 在CGI模式中,php-cgi在此便退出了。


3)PHP-CGI

PHP-CGI是PHP自带的FastCGI管理器。

PHP-CGI的不足:

1. php-cgi变动php.ini配置后需重启php-cgi才能让新的php-ini生效,不能够平滑重启。

2. 直接杀死php-cgi进程,php就不能运行了。(PHP-FPM和Spawn-FCGI就没有这个问题,守护进程会平滑重新生成新的子进程。)

4)PHP-FPM

PHP-FPM是一个PHP FastCGI管理器,是只用于PHP的。

PHP-FPM实际上是PHP源代码的一个补丁,旨在将FastCGI进程管理整合进PHP包中。必须将它patch到你的PHP源代码中,在编译安装PHP后才可使用。

 

3、SAPI

下图为SAPI的简单示意图:

SAPI(Server abstraction API),它提供了一个接口,使得PHP能够和其余应用进行交互数据。

 

1)PHP执行的两个阶段,开始和结束

开始阶段:

a. 模块初始化阶段(MINIT), 在整个SAPI生命周期内(例如Apache启动之后的整个生命周期内或者命令行程序整个执行过程当中), 该过程只进行一次

b. 模块激活阶段(RINIT),该过程发生在请求阶段, 例如经过url请求某个页面,则在每次请求以前都会进行模块激活(RINIT请求开始)

结束阶段:

a. 停用模块(RSHUTDOWN,对应RINIT)

b. 在SAPI生命周期结束(Web服务器退出或者命令行脚本执行完毕退出)时关闭模块(MSHUTDOWN,对应MINIT)

 

2)单进程SAPI生命周期

CLI/CGI模式的PHP属于单进程的SAPI模式。这类的请求在处理一次请求后就关闭。也就是只会通过以下几个环节:

开始 - 请求开始 - 请求关闭 - 结束。SAPI接口实现就完成了其生命周期。

a. 启动:初始化若干全局变量,初始化若干常量,初始化Zend引擎和核心组件,解析php.ini,全局操做函数的初始化,初始化静态构建的模块和共享模块(MINIT),禁用函数和类

b. 激活:激活Zend引擎,激活SAPI,环境初始化,模块请求初始化

c. 运行:要解析执行的文件,须要作词法分析、语法分析和中间代码生成操做,返回此文件的全部中间代码

d. 关闭:关闭请求的过程是一个若干个关闭操做的集合

e. 结束:flush,关闭Zend引擎

 

3)多进程SAPI生命周期

一般PHP是编译为apache的一个模块来处理PHP请求。

  Apache通常会采用多进程模式, Apache启动后会fork出多个子进程,每一个进程的内存空间独立,每一个子进程都会通过开始和结束环节, 不过每一个进程的开始阶段只在进程fork出来以来后进行,在整个进程的生命周期内可能会处理多个请求。

 

4)多线程的SAPI生命周期

  多线程模式和多进程中的某个进程相似,不一样的是在整个进程的生命周期内会并行的重复着 请求开始-请求关闭的环节

 

4、PHP脚本的执行

SAPI处于PHP整个架构较上层,而真正脚本的执行主要由Zend引擎来完成。

<?php
$str = "Hello, World!\n";
echo $str;

a. 如上例中, 传递给php程序须要执行的文件, php程序完成基本的准备工做后启动PHP及Zend引擎, 加载注册的扩展模块。

b. 初始化完成后读取脚本文件,Zend引擎对脚本文件进行词法分析,语法分析。

c. 编译成opcode执行。 若是安装了apc之类的opcode缓存, 编译环节可能会被跳过而直接从缓存中读取opcode执行。

不少编程语言都使用lex/yacc或他们的变体(flex/bison)来做为语言的词法语法分析生成器, 好比PHP、Ruby、Python以及MySQL的SQL语言实现。

PHP是构建在Zend虚拟机(Zend VM)之上的。PHP的opcode就是Zend虚拟机中的指令。

 

 

参考资料:

http://www.cnblogs.com/hongfei/archive/2012/06/12/2547119.html   PHP的执行原理/执行流程

http://www.php-internals.com/book/?p=chapt02/02-01-php-life-cycle-and-zend-engine   生命周期和Zend引擎

http://www.php-internals.com/book/?p=chapt02/02-02-01-apache-php-module  Apache模块

http://www.php-internals.com/book/?p=chapt02/02-02-03-fastcgi   FastCGI

http://segmentfault.com/q/1010000000256516    FastCgi与PHP-fpm之间是个什么样的关系

http://www.cnblogs.com/skynet/p/4173450.html  Nginx + CGI/FastCGI + C/Cpp

http://www.php-internals.com/book/?p=chapt02/02-02-00-overview   SAPI概述

http://rapheal.sinaapp.com/2013/11/14/php_zend_lex/  PHP-Zend引擎剖析之词法分析

http://rapheal.sinaapp.com/2013/11/20/php_zend_hello_world/  PHP-Zend引擎剖析之Hello World

http://www.nowamagic.net/librarys/veda/detail/1287    一次请求生命周期

相关文章
相关标签/搜索