PHP设计理念及特点

  • 多进程模型:不同请求之间,互补干涉,保证一个请求挂掉不会影响整体服务。
  • 弱类型语言:变量类型并不是一开始就确当不变,运行中才会确定并可能发生隐式或显示的类型转换。web开发方便、高效。
  • 引擎(Zend)+ 组件(ext)的模式,降低内部耦合。
  • 中间层(sapi),隔绝web server 和 php。

PHP核心架构

从上到下四层体系

  • Zend引擎:PHP内核部分,将PHP代码翻译(词法、语法解析)为可执行opcode的处理并实现相应的处理方法、实现基本数据接口(hashtable、oo) 、内存分配及管理、提供了相应的API方法供外部调用,是一切的核心,所有外围功能围绕Zend实现。

  • Extension:围绕Zend引擎,通过组件方式提供各种基础服务,常见的各种内置函数、标准库都是通过extension来实现。

  • SAPI:全称是Server Application Programming Interface服务端应用编程接口,SAPI通过一系列钩子函数,使得PHP可以和外围交互数据。 SAPI将PHP本身和上层应用解耦隔离,PHP可以不用考虑如何针对不同应用进行兼容,而应用本身也可以针对自己的特点实现不同的处理方式。

    • apache2handler:以apache作为webserver,采用mod_PHP模式运行时候的处理方式。
    • cgi:webserver和PHP直接的另一种交互方式,fastcgi协议,也是异步webserver所唯一支持的方式。
    • cli:命令行调用模式。
  • 上层应用:编写的PHP程序,通过不同的SAPI方式得到各种各样的应用模式。

PHP执行流程

PHP实现了一个典型的动态语言执行过程:拿到一段代码后,经过词法分析、语法解析等阶段后, 源程序会被翻译成一个个指令(opcodes),然后ZEND虚拟机顺序执行这些指令完成操作。

执行的核心是opcode指令。opcode是PHP程序执行最基本的单位

ZEND 引擎介绍

Zend引擎作为PHP内核,经典设计机制介绍:

  • 实现hashTable数据结构
    • 数组
    • 函数符号表、全部变量基于hashTable来实现
    • 双向链表,提供正向、反向遍历数组的功能
  • 散列结构,典型的hash表模型
    • 通过链表别的方式来解决冲突
    • hash表数目满了,本身以2倍的方式扩容
  • 双向链表
    • Zend hash table 通过一个链表结构,实现元素的线性遍历
    • 不使用单向链表,目的就是快速删除,避免遍历
  • 关联数组
    • hashTable应用
    • nKeyLength标识key长度来快速判定,空间换时间,key->value快速查找时

PHP变量实现原理

PHP变量管理-引用计数和写时拷贝

在进行赋值操作时,zend将变量指向相同的zval同时ref_count++,在unset操作时,对应的ref_count-1。只有ref_count减为0时才会真正执行销毁操作。 如果是引用赋值,则zend会修改is_ref为1。

PHP局部变量和全局变量的实现

两个符号表(symbol_table和 active_symbol_table),其中前者用来维护全局变量。后者是一个指针,指向当前活动的变量符号表,当程序进入到某个函数中时, zend 就会为它分配一个符号表x同时将active_symbol_table指向a。通过这样的方式实现全局、局部变量的区分。

获取变量值:PHP的符号表是通过hash_table实现的,对于每个变量都分配唯一标识,获取的时候根据标识从表中找到相应zval返回。

函数中使用全局变量:在函数中,我们可以通过显式申明global来使用全局变量。在active_symbol_table中创建symbol_table中同名变量的引用(引用变量的值要更新大家会一起更新),如果symbol_table中没有同名变量则会先创建。

参考

https://www.laruence.com/2018/04/08/3170.html