PHP内核的实现和世界上绝大数的程序一样,接收输入数据,做相应处理后输出结果。用PHP编写的代码就是输入数据,PHP内核对编写的代码进行解释和运算,最后返回运算结果。当编写的PHP代码给内核去执行的时候,PHP内核会对PHP代码进行词法分析、语法分析。词法分析把PHP代码分割成一个个的单元(token),语法分析则将这些单元转换为Zend Engine

可执行的操作。然后PHP内部的Zend Engine对这些操作进行顺序执行。Zend Engine时PHP内核的核心部分,负责最终操作的执行和结果的返回

SAPI接口

SAPI(Server Application Programming Interface) 是PHP具体应用的编程接口。脚本执行的开始都是以SAPI接口实现开始的。只是不同的SAPI接口实现会完成他们特定的工作

web服务器会将请求转发给SAPI,SAPI转发给zendEngine。

PHP常用的SAPI接口有CGI,CLI,FastCGI,Apache2Handler(mod_php模式运行)

无论使用何种SAPI接口都会经过两个主要的阶段,处理请求之前的开始阶段和请求之后的结束阶段,开始阶段有两个过程,第一个过程是模块初始化阶段(MINIT)在整个SAPI生命周期内该过程只进行一次,第二个过程是模块激活阶段(RINIT)该过程发生在请求阶段。请求处理后就进入了结束阶段,一般脚本执行到末尾或者通过调用exit()或die()函数,PHP都将进入结束阶段。结束阶段也分为两个环节,一个请求结束后停用模块,一个SAPI生命周期结束时关闭模块。

单进程SAPI生命周期

CLI/CGI模式的PHP属于单进程的SAPI模式。这类的请求在处理一次请求后就关闭。也就是只会经过如下几个环节: 开始 - 请求开始 - 请求关闭 - 结束 SAPI接口实现就完成了其生命周期。如图2.1所示:

图2.1 单进程SAPI生命周期

多进程SAPI生命周期

通常PHP是编译为apache的一个模块来处理PHP请求。Apache一般会采用多进程模式, Apache启动后会fork出多个子进程,每个进程的内存空间独立,每个子进程都会经过开始和结束环节, 不过每个进程的开始阶段只在进程fork出来以来后进行,在整个进程的生命周期内可能会处理多个请求。 只有在Apache关闭或者进程被结束之后才会进行关闭阶段,在这两个阶段之间会随着每个请求重复请求开始-请求关闭的环节。 如图2.2所示:

图2.2 多进程SAPI生命周期

多线程的SAPI生命周期(xampp apache2handler sapi 采用该模式)

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

图2.3 多线程SAPI生命周期

APACHE2HANDLER

php 代码的执行的更多相关文章

  1. Java中普通代码块,构造代码块,静态代码块执行顺序

    //执行顺序:(优先级从高到低.)静态代码块>mian方法>构造代码块>构造方法. 其中静态代码块只执行一次.构造代码块在每次创建对象是都会执行. 1 普通代码块 1 //普通代码块 ...

  2. python3下载远程代码并执行

    第一步: 先在gist之类的网站上贴上代码,目的不是高亮,而可以raw的形式获取代码,这样可以省掉处理html的时间,我这里用的是pasteraw: 远程上的代码:http://cdn.pastera ...

  3. request重定向或者是response转发请求后面的代码依然执行

    调用response.redirect(),或者request.getRequestDispatcher(loginAddr).forward(request,response);后,后面的代码照样执 ...

  4. js eval()函数 接收一个字符串,做为js代码来执行。 如: s='var d="kaka"'; 或者s=‘function (code){return code }’;

    eval函数接收一个参数s,如果s不是字符串,则直接返回s.否则执行s语句.如果s语句执行结果是一个值,则返回此值,否则返回undefined. 需要特别注意的是对象声明语法“{}”并不能返回一个值, ...

  5. try{...} catch {...} finally{...} 各种情况代码的执行情况

    try { int i = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("in the 'try'"); } ca ...

  6. openresty源码剖析——lua代码的执行

    上一篇文章中我们讨论了openresty是如何加载lua代码的 那么加载完成之后的lua代码又是如何执行的呢 ##代码的执行  在init_by_lua等阶段  openresty是在主协程中通过lu ...

  7. JavaSe:代码块执行顺序

    //执行顺序:(优先级从高到低.)静态代码块>mian方法>构造代码块>构造方法. 其中静态代码块只执行一次.构造代码块在每次创建对象是都会执行. //普通代码块:在方法或语句中出现 ...

  8. javascript系列1--把字符串当代码来执行

    转发请标明来源:http://www.cnblogs.com/johnhou/p/javascript.html  请尊重笔者的劳动成果  --John Hou 在javascript中有多种方法可以 ...

  9. Java静态代码块、构造代码块执行顺序问题

    package com.zxl.staticdemo; public class BlockTest { static { System.out.println("BlockTest静态代码 ...

  10. 怎样解决if __name__ == "__main__":下面的代码没有执行的问题

    很多初学者可能在用pycharm运行代码时会出现if __name__ == "__main__":下面的代码没有执行的问题,出现这类问题的原因是unittest运行姿势造成的,如 ...

随机推荐

  1. 如何在Ubuntu上使用Glances监控系统

    导读 Glances 是一个用于监控系统的跨平台.基于文本模式的命令行工具.它是用 Python 编写的,使用 psutil 库从系统获取信息.你可以用它来监控 CPU.平均负载.内存.网络接口.磁盘 ...

  2. HDU 2191悼念512汶川大地震遇难同胞——珍惜如今,感恩生活(多重背包)

    HDU 2191悼念512汶川大地震遇难同胞--珍惜如今.感恩生活(多重背包) http://acm.hdu.edu.cn/showproblem.php?pid=2191 题意: 如果你有资金n元, ...

  3. android开发中,在java中怎样使用c提供过来char*

    这个char*假设是一般的字符串的话,作为string传回去就能够了.假设是含有'\0'的buffer,最好作为bytearray传出,由于能够制定copy的length.假设copy到string, ...

  4. 在线激活Pycharm(亲测有效)

    (1)在激活界面的License server输入:http://idea.liyang.io:或者:点击help→Register→License sever ,输入http://idea.liya ...

  5. C# t4模版引擎笔记 引入外部dll

    <#@ assembly name="D:\Documents\Downloads\Util\Util\bin\Debug\Util.dll" #> <#@ im ...

  6. iOS:一个Cell中设置另外一个Cell中的button

    场景: 子类化Cell中有button,拥有选中式样,点击第一个Cell中的button后,Cell一中的button获得选中式样.可是当点击Cell二中的button时.Cell一中的button选 ...

  7. yum安装epel后报错

    Loaded plugins: fastestmirror, refresh-packagekit, security Loading mirror speeds from cached hostfi ...

  8. PE下挂载注册表文件然后清除系统托盘空白图标缓存

    清除了右下角通知栏图标缓存TrayNotify(否则会出现一堆空白图标)清除缓存批处理脚本.bat如何在PE系统环境下清除宿主系统的托盘图标缓存? 清除了右下角通知栏图标缓存TrayNotify(否则 ...

  9. 521. Longest Uncommon Subsequence I【easy】

    521. Longest Uncommon Subsequence I[easy] Given a group of two strings, you need to find the longest ...

  10. composer 初始化办法和方法

    php -r "readfile('https://getcomposer.org/installer');" > composer-setup.php php -r &qu ...