PHP运行原理之opcode

本文介绍了PHP的运行原理,重点解析了opcode的概念及其在PHP脚本执行过程中的作用。PHP执行过程包括词法分析、语法分析、编译和执行四个步骤。opcode是PHP编译后的中间语言,用于提升脚本执行速度。通过使用opcode缓存如APC,可以避免重复编译,提高性能。此外,文章探讨了单引号和双引号在PHP中创建字符串的差异,指出在不涉及变量替换时,单引号字符串的处理速度更快,因为其在词法规则和编译阶段有不同的处理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是opcode?

  • opcode是PHP脚本编译后的中间语言(相似于Java语言的字节码–byte-code),是PHP引擎(Zend)执行的语言。
  • PHP引擎在执行PHP脚本时会分为四步来进行:
    1、扫描、词法分析:将PHP代码转换为token(语言片段)
    2、语法分析:将token转换为简单而有意义的表达式
    3、编译:将所有表达式转换成opcodes
    4、执行:顺序执行(通常为由上至下)opcodes,每次一条,从而实现脚本功能
    
    扩展: 执行每个PHP脚本都会遵循上面的四个步骤,为了提高PHP脚本的执行速度可以使用一些cache(如APC)来缓存opcodes,这样每次脚本执行时就能减少前三步的消耗,从而提高执行速度。
  • 学过编译原理使得对编译原理中的词法分析步骤有所了解,Lex就是一个词法分析的依据表。 Zend/zend_language_scanner.c会根据Zend/zend_language_scanner.l(Lex文件),来输入的 PHP代码进行词法分析,从而得到一个一个的“词”,PHP提供了一个函数叫token_get_all,这个函数就可以将一段PHP代码通过查询词法分析表翻译为Tokens。在这个Tokens中,源码中的字符串,字符,空格,都会原样返回。每个源代码中的字符,都会出现在相应的顺序处。而其他的比如标签,操作符,语句,都会被转换成一个包含俩部分的数组(类似于数组): Token 和ID (也就是在Zend内部的改Token的对应码,比如,T_ECHO,T_STRING),和源码中的原来的内容;
  • 到了语法分析阶段,首先会丢弃Tokens Array中的多于的空格,然后将剩余的Tokens转换成一个一个的简单的表达式;
  • 到了编译阶段,会把Tokens编译成一个个op_array, 每个op_arrayd包含如下5个部分:
    1.Opcode数字的标识	指明了每个op_array的操作类型,比如add , echo
    2.结果       		存放Opcode结果
    3.操作数1  			给Opcode的操作数
    4.操作数2
    5.扩展值   			1个整型用来区别被重载的操作符
    如 <?php echo "hello world"; ?>会被编译为:
    * ZEND_ECHO  'Hello World'
    另外操作数的作用是用来对变量进行处理的,如:
    <?php
    	$a = 1;
    	echo $a;
    ?>
    编译后的opcode为:
    * ZEND_ASSIGN  !0 11赋值给!0
    * ZEND_ECHO    !0		输出!0
    这里我们并没有看到$a这个变量,我们先来看一下操作数的组成:
    	op_type:IS_CONST, IS_TMP_VAR, IS_VAR, IS_UNUSED, or IS_CV
    	u: 			一个联合体,根据op_type的不同,分别用不同的类型保存了这个操作数的值(const)或者左值(var)
    IS_CONST为一个值;
    IS_TMP_VAR是一个临时变量,保存一些op_array的结果,以便接下来的op_array使用,
    	这种的操作数的u保存着一个指向变量表的一个句柄(整数),这种操作数一般用“~”开头;
    	“`~0`”表示变量表的0号未知的临时变量;
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值