手机做印章网站,html实例百度网页制作代码,wordpress 如何汉化,500个公司取名大全Opcode是一种PHP脚本编译后的中间语言#xff0c;就像Java的ByteCode,或者.NET的MSL#xff0c;举个例子#xff0c;比如你写下了如下的PHP代码#xff1a;echoHello World;$a 1 1;echo$a;?PHP执行这段代码会经过如下4个步骤(确切的来说#xff0c;应该…Opcode是一种PHP脚本编译后的中间语言就像Java的ByteCode,或者.NET的MSL举个例子比如你写下了如下的PHP代码echoHello World;$a 1 1;echo$a;?PHP执行这段代码会经过如下4个步骤(确切的来说应该是PHP的语言引擎Zend)1.Scanning(Lexing),将PHP代码转换为语言片段(Tokens)2.Parsing, 将Tokens转换成简单而有意义的表达式3.Compilation, 将表达式编译成Opocdes4.Execution,顺次执行Opcodes每次一条从而实现PHP脚本的功能。题外话:现在有的Cache比如APC,可以使得PHP缓存住Opcodes这样每次有请求来临的时候就不需要重复执行前面3步从而能大幅的提高PHP的执行速度。那什么是Lexing? 学过编译原理的同学都应该对编译原理中的词法分析步骤有所了解Lex就是一个词法分析的依据表。Zend/zend_language_scanner.c会根据Zend/zend_language_scanner.l(Lex文件),来输入的PHP代码进行词法分析从而得到一个一个的“词”PHP4.2开始提供了一个函数叫token_get_all,这个函数就可以讲一段PHP代码Scanning成Tokens如果用这个函数处理我们开头提到的PHP代码将会得到如下结果:Array([0] Array([0] 367[1] Array([0] 316[1] echo)[2] Array([0] 370[1])[3] Array([0] 315[1] Hello World)[4] ;[5] Array([0] 370[1])[6] [7] Array([0] 370[1])[8] Array([0] 305[1] 1)[9] Array([0] 370[1])[10] [11] Array([0] 370[1])[12] Array([0] 305[1] 1)[13] ;[14] Array([0] 370[1])[15] Array([0] 316[1] echo)[16] Array([0] 370[1])[17] ;)分析这个返回结果我们可以发现源码中的字符串字符空格都会原样返回。每个源代码中的字符都会出现在相应的顺序处。而其他的比如标签操作符语句都会被转换成一个包含俩部分的Array:Token ID(也就是在Zend内部的改Token的对应码比如,T_ECHO,T_STRING)和源码中的原来的内容。接下来就是Parsing阶段了Parsing首先会丢弃TokensArray中的多于的空格然后将剩余的Tokens转换成一个一个的简单的表达式1.echo a constant string2.add two numbers together3.store the result of the prior expression toa variable4.echo a variable然后就改Compilation阶段了它会把Tokens编译成一个个op_array,每个op_arrayd包含如下5个部分1.Opcode数字的标识指明了每个op_array的操作类型比如add ,echo2.结果 存放Opcode结果3.操作数1 给Opcode的操作数4.操作数25.扩展值 1个整形用来区别被重载的操作符比如我们的PHP代码会被Parsing成:* ZEND_ECHO Hello World* ZEND_ADD ~0 1 1* ZEND_ASSIGN !0 ~0* ZEND_ECHO !0呵呵你可能会问了我们的$a去那里了恩这个要介绍操作数了每个操作数都是由以下俩个部分组成a)op_type : 为IS_CONST, IS_TMP_VAR, IS_VAR,IS_UNUSED, or IS_CVb)u,一个联合体根据op_type的不同分别用不同的类型保存了这个操作数的值(const)或者左值(var)而对于var来说每个var也不一样IS_TMP_VAR,顾名思义这个是一个临时变量保存一些op_array的结果以便接下来的op_array使用这种的操作数的u保存着一个指向变量表的一个句柄(整数)这种操作数一般用~开头比如~0,表示变量表的0号未知的临时变量IS_VAR 这种就是我们一般意义上的变量了,他们以$开头表示IS_CV表示ZE2.1/PHP5.1以后的编译器使用的一种cache机制这种变量保存着被它引用的变量的地址当一个变量第一次被引用的时候就会被CV起来以后对这个变量的引用就不需要再次去查找active符号表了CV变量以开头表示。这么看来我们的$a被优化成!0了。