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代码。