对PHP内核的再梳理

Posted by onceme on Saturday, January 19, 2019

TOC

这篇文章是对PHP内核的重新梳理,尽量用简单的语言来描述清楚PHP内核的机制,一次请求下来所经过的流程,PHP5与PHP7内核对比,PHP的优势以及它的局限

首先介绍PHP的基本结构
  • PHP本身没有与外界交互的能力,所以需要一种类似于shell壳程序的东西,叫做SAPI
  • PHP常见的几种API机制
    • 以动态链接库的形式嵌入apache的module进程
    • cgi方式,web前端服务器(apache/nginx)每次请求都发送给PHP服务器,php服务器则每次都fork一个进程来执行这个请求
    • fast-cgi方式, PHP服务器提前启动好一定数量的,每次web服务器发送的请求都会倍分配给其中某一个worker进程,避免了每次初始化进程与销毁进程的开销
  • 总的来说,PHP选择以外挂服务管理程序的方式来让PHP对外提供服务
  • Zend引擎

    • 编译器: 负责将PHP代码编译为抽象语法树,然后进一步编译为可执行的opcodes,这 个过程相当于GCC的工作,编译器是一个语言实现的基础
    • 执行器: 负责执行编译器输出的opcodes,也就是执行PHP脚本中编写的代码逻辑
  • PHP扩展

PHP-FPM的多进程模型
  • 首先有一个master管理进程
  • 按照static,dynamic,ondemand等模式对worker进程进行管理
PHP的执行过程
  • php_module_startup() PHP运行环境的初始化,以及扩展的加载
  • php_request_startup() gc_rest() 重置上次请求后产生的所有变量
  • php_excute_script() 编译并执行php代码
  • php_request_shutdown() 依次调用各扩展的RSHUTDOWN函数

变量
  • 变量由zval与zend_val实现,zval中包含zend_val类型的成员变量
  • PHP中局部变量分配在zend_execute_data结构上
  • 局部变量在执行之初分配,然后在执行结束时释放,这是局部变 量的生命周期,
  • 局部变量中有一种特殊的类型:静态变量,它们不会在函数执行完后释放,当程序执行离开函数域时静态变量的值被保留下来
  • 静态变量保存在zend_op_array->static_variables
  • 静态变量只会初始化一次,注意:它的初始化发生在编译阶段而不是执行阶段
  • 这个特性也意味着静态变量初始的值不能是变量,比如: static $count = $xxx;这样定义将会报错

comments powered by Disqus
Ï