PHP 7 源码学习 序&第一、二章
PHP 7 源码学习 序&第一、二章
零、序
不想多说,万一坚持不下来呢。
搞安全就是不按常理利用代码,所以常常要从底层绕过开发者认为安全的防护。审计代码和看源码的能力我觉得蛮重要的,尤其是研究新漏洞的时候,有时候答案就藏在源码里。我希望能通过尝试着学习PHP源码来学习源码该如何看,另一方面加深对PHP机制的理解。希望不会鸽掉吧~
第一章 PHP 7 概况
1. PHP简史
- 1996年 Rasmus Lerdorf发布相对完善的2.0版本
- 2000年夏初,4.0版本发布,Zend引擎正式登场,相比3.0,最高可以有10倍的性能提升
- 2004年7月,PHP 5 正式发布,Zend引擎升级到2.0。PHP 5 最大的特点是引入了面向对象的全部机制、类型提示和异常处理机制
- 2005年PHP社区发起PHP 6 项目,但是由于种种原因取消。但是大量的新功能陆续被添加进了PHP 5.x 版本,例如命名空间、匿名函数、闭包等
- 2015年夏天,PHP 7 发布了第一个Alpha版本,有着非常大的革新,尤其是性能显著提升。
2. PHP 7 的调试与工具
-
GDB
$ gdb php (gdb) b main (gdb) r test.php ...
-
vld扩展
PHP代码的执行实际上是在执行代码解析后的各种opcode。通过vld扩展可以很方便地看到执行过程中的opcode。$ php -dvld.active=1 vld.php
-
Source Insight
Windows下一款IDE,我使用这个来学习源码
第二章 初识PHP 7 源码整体框架
1. PHP 7 语言的执行原理
- 第1步:源码通过词法分析得到Token
该步骤的词法分析器使用Re2C实现 - 第2步:基于语法分析器生成抽象语法树(AST)
语法分析器基于Bison实现。语法分析使用了BNF(Backus-Naur Form,巴科斯范式)来表达文法规则,Bison借助状态机、状态转移表和压栈、出栈等一系列操作,生成抽象语法树。 - 第3步:抽象语法树转换为opcodes(opcode指令集合),PHP解释执行opcodes。
opcode是PHP 7 定义的一组指令标识,指令对应着相应的handler(处理函数)。当虚拟机调用opcode,会找到opcode背后的处理函数,执行真正的处理。例如:echo对应的opcode是ZEND_ECHO
2.PHP 7 内核架构
- Zend引擎(核心)
词法/语法分析、ASt编译和opcodes的执行均在Zend引擎中实现。此外,变量设计、内存管理、进程管理都在这实现 - PHP层
处理来自外部的交互 - SAPI
Server API,其中包含了常见的cli SAPI和fpm SAPI。PHP定义好输入/输出规范,依据此规范与PHP交互的一方都可以称为Server - 扩展部分
3.PHP 7 源码结构初步介绍
sapi
sapi目录是对输入和输出层的抽象,是PHP提供对外服务的规范
常见SAPI包括:
- apache2handler:Apache扩展
- cgi-fcgi:编译后生成支持CGI协议的可执行程序
- fpm-fcgi:PHP官方提供的FastCGI进程管理器
- cli:命令行交互接口
Zend
重点部分包括
- 内存管理模块
- 垃圾回收
- 数组实现
main
main目录是SAPI层和Zend层的粘合剂,起到承上启下的作用。
ext
PHP扩展相关的目录
TSRM
Thread Safe Resource Manager----线程安全资源管理器