php的词法分析、语法分析大多采用Flex/Bison处理
在语法分析完成后,由zend引擎生成中间代码(使用opcache可以省略编译阶段)opcode,PHP是构建在Zend虚拟机(Zend VM)之上的。PHP的opcode就是Zend虚拟机中的指令
在PHP实现内部,opcode由如下的结构体表示:
struct _zend_op {
opcode_handler_t handler; // 执行该opcode时调用的处理函数
znode result;
znode op1;
znode op2;
ulong extended_value;
uint lineno;
zend_uchar opcode; // opcode代码
};
由上可知所谓的opcode就是zend虚构的有c结构体标识的一种指令集(大概有130多个)
例如如下代码是在编译器遇到print语句的时候进行编译的函数:
void zend_do_print(znode *result,const znode *arg TSRMLS_DC)
{
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->result.op_type = IS_TMP_VAR;
opline->result.u.var = get_temporary_variable(CG(active_op_array));
opline->opcode = ZEND_PRINT;
opline->op1 = *arg;
SET_UNUSED(opline->op2);
*result = opline->result;
}
这个函数新创建一条zend_op,将返回值的类型设置为临时变量(IS_TMP_VAR),并为临时变量申请
空间, 随后指定opcode为ZEND_PRINT,并将传递进来的参数赋值给这条opcode的第一个操作数。这样
在最终执行这条opcode的时候, Zend引擎能获取到足够的信息以便输出内容。(实质就是zend解析print语句时会通过zend_do_print函数去生成这个中间代码opcode)
opcode被保存在op_array结构体中,再由execute函数顺序执行opcode代码。