Php源码学习笔记
编译型语言的编译过程
词法分析,在这个阶段将源代码转换为单词 token
语法分析,将token转为语法树
语义分析,对语法树进行分析并检查语义错误
- 这个阶段通过符号表判断作用域和类型,符号表记录了各种变量方法和类的声明。 需要注意这里的符号表是一个栈, 因为代码总是按顺序执行的,所以其实只要找到最近的符号就ok。 这里不必担心嵌套的作用域变量可能会重名, 因为每检查完一个方法,这个方法使用到的变量已经确定了,不用再检查了,方法内部的符号就会从符号表移除 (一般语言都是先声明后调用, js 的变量提升,代码层面可能是先调用后声明, 但是执行阶段可能不是这样)。
中间代码生成, 中间代码这里主要有 头 代码 数据, 这三部分。
- 头主要包含各种声明, 其实差不多就是上个阶段剩下的符号表。 在这个阶段有些声明的方法在内存中的位置已经确定了,有的还不确定,比如引入了外部的方法之类的。
- 代码。
- 数据。
目标代码生成。
- 这个阶段,连接其他的中间代码文件,把缺少的内存地址补完,生成可以运行的二进制代码。
php 的执行过程
- 词法分析,将源代码转换为 token。
- 语法分析,将 token 转为 AST 语法树。
- 编译器将 AST 转换为 opcodes (opcode 指令集合)。
- 解释器解释执行 opencodes。
一些小细节
- php 的内置函数
token_get_all()
可以查看 php代码 生成的 token。 - php 内核作者之一 Nikic 编写的可以将 php源码生成 AST 的工具。 github.com/nikic/PHP-Parser.git
- opcode 是Zend引擎可以直接运行的指令, 有点像 java 的字节码, opcache 缓存的就是 opcodes. 可以通过 vld 扩展查看 php源码生成的 opcode . github.com/derickr/vld
- c 编译出来的目标代码是操作系统的可以执行的指令,opcode 是 Zend 引擎可以执行的指令,它们是有区别的。
备注
笔记的内容来自于 php7底层设计与源码实现
这本书和一些大佬的指点和我自己的总结。可能有理解错误的地方,大家也可以直接买内本书看。
本作品采用《CC 协议》,转载必须注明作者和本文链接
还有后续吗 ?
带带弟弟! 写了一段时间c感觉玩不明白 有什么php内核入门的学习资料么