热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

理解php原理的opcodes(操作码)

现自己对php的原理基本上都不了解,特别是深层的~呵呵,继续努力,特转载喜欢的朋友可以研究下。
Opcondes是一种php脚本编译后的中间语言,就像Java的Byte Code,或者.NET 的MSL 。(都没了解过~)

  举个文中的例子

代码如下:


  echo "Hello World";
  $a = 1 + 1;
   echo $a;
  ?>


PHP执行这段代码会经过如下4个步骤(确切的来说,应该是PHP的语言引擎Zend)

代码如下:


  1.Scanning(Lexing) (扫描),将PHP代码转换为语言片段(Tokens)
  2.Parsing(语法分析), 将Tokens转换成简单而有意义的表达式
  3.Compilation(编译), 将表达式编译成Opocdes
  4.Execution(执行编译后的结果), 顺次执行Opcodes,每次一条,从而实现PHP脚本的功能。


  其中他还提到一句:“现在有的Cache比如APC,可以使得PHP缓存住Opcodes,这样,每次有请求来临的时候,就不需要重复执行前面3步,从而能大幅的提高PHP的执行速度。 ” 这可能是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首先会丢弃Tokens Array中的多于的空格,然后将剩余的Tokens转换成一个一个的简单的表达式

代码如下:


1.echo a constant string
2.add two numbers together
3.store the result of the prior expression to a variable
4.echo a variable


然后就改Compilation阶段了,它会把Tokens编译成一个个op_array, 每个op_arrayd包含如下5个部分:

代码如下:


1.Opcode数字的标识,指明了每个op_array的操作类型,比如add , echo
2.结果 存放Opcode结果
3.操作数1 给Opcode的操作数
4.操作数2
5.扩展值 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了。
总结:


1.php的执行顺序是: -> php程序
          -> 被Scanning(扫描转换为Tokens(语言片段))
          -> 被Parsing(语法分析,将Tokens转换成简单而有意义的表达式)
          -> Compilation(编译,将表达式编译成Opocdes(操作码))
-> Execution(顺序执行编译后的结果)
2. APC(Alternative PHP Cache)的缓存机制可以缓存住Opcodes,这样,下次有请求来临的时候,就不需要重复执行前面3步,从而能大幅的提高PHP的执行速度。 这可能是php执行速度比较快的原因之一

补充:
apc,zend optimize是之所以能够加速php
就是因为他可以缓存opcode
并不是zend引擎本身自带的功能
zend引擎默认是一个轮回中任何一项都要走的
推荐阅读
  • Windows7企业版怎样存储安全新功能详解
    本文介绍了电脑公司发布的GHOST WIN7 SP1 X64 通用特别版 V2019.12,软件大小为5.71 GB,支持简体中文,属于国产软件,免费使用。文章还提到了用户评分和软件分类为Win7系统,运行环境为Windows。同时,文章还介绍了平台检测结果,无插件,通过了360、腾讯、金山和瑞星的检测。此外,文章还提到了本地下载文件大小为5.71 GB,需要先下载高速下载器才能进行高速下载。最后,文章详细解释了Windows7企业版的存储安全新功能。 ... [详细]
  • Linux环境变量$PATH的作用及使用方法
    本文介绍了Linux环境变量$PATH的作用及使用方法。$PATH是一个由多个目录组成的变量,用冒号分隔。当执行一个指令时,系统会按照$PATH定义的目录顺序搜索同名的可执行文件,如果有多个同名指令,则先找到的会被执行。通过设置$PATH变量,可以在任何地方执行指令,无需输入绝对路径。 ... [详细]
  • PHP组合工具以及开发所需的工具
    本文介绍了PHP开发中常用的组合工具和开发所需的工具。对于数据分析软件,包括Excel、hihidata、SPSS、SAS、MARLAB、Eview以及各种BI与报表工具等。同时还介绍了PHP开发所需的PHP MySQL Apache集成环境,包括推荐的AppServ等版本。 ... [详细]
  • asp中如何嵌入python的简单介绍
    本文目录一览:1、如何在IIS中执行Python脚本 ... [详细]
  • vb.net不用多线程如何同时运行两个过程?不用多线程?即使用多线程,也不会是“同时”执行,题主只要略懂一些计算机编译原理就能明白了。不用多线程更不可能让两个过程同步执行了。不过可 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 现在学vb6还靠得住么?语言只是工具,关键是思想。程序=算法+数据结构。除了汇编,其他语言都靠不住。随着时代的进步,很多语言跟不上开发的要求。从面向过程到面向对象,与其说是思想的进步,不如说是为了适应高速开发。除了底层汇编语言,还有那些能适应高速开发的语言。每种语言都是很有趣的。 ... [详细]
  • 本文详细介绍了如何创建和使用VUE uni-app开发环境,包括通过HBuilderX可视化界面和通过vue-cli命令执行的方法。文章内容简单清晰,易于学习与理解。通过学习本文,读者可以深入了解VUE uni-app开发环境,并通过实践验证掌握具体的使用情况。编程笔记将为读者推送更多相关知识点的文章,欢迎关注! ... [详细]
  • 本文介绍了一个从入门到高手的VB.NET源代码,通过学习这些源代码,可以在21天内成为VB.NET高手。文章提供了下载地址,并提醒读者加入作者的QQ群和收藏作者的博客。 ... [详细]
  • 全面介绍Windows内存管理机制及C++内存分配实例(四):内存映射文件
    本文旨在全面介绍Windows内存管理机制及C++内存分配实例中的内存映射文件。通过对内存映射文件的使用场合和与虚拟内存的区别进行解析,帮助读者更好地理解操作系统的内存管理机制。同时,本文还提供了相关章节的链接,方便读者深入学习Windows内存管理及C++内存分配实例的其他内容。 ... [详细]
  • GTX1070Ti显卡怎么样?GTX1070Ti显卡首发图赏+参数解读与拆解图
    先来简单回顾一下今年的显卡市场,nvidia自从发布了帕斯卡架构新品之后,可以说是一直都主宰着高端游戏显卡市场,虽说amd也憋了一个hbm2的vega64出来,然而即使是最高贵的水 ... [详细]
  • 本文介绍了禅道作为一款国产开源免费的测试管理工具的特点和功能,并提供了禅道的搭建和调试方法。禅道是一款B/S结构的项目管理工具,可以实现组织管理、后台管理、产品管理、项目管理和测试管理等功能。同时,本文还介绍了其他软件测试相关工具,如功能自动化工具和性能自动化工具,以及白盒测试工具的使用。通过本文的阅读,读者可以了解禅道的基本使用方法和优势,从而更好地进行测试管理工作。 ... [详细]
  • 本文介绍了某点评网的搜索策略,包括名称和地址的匹配策略,模糊匹配的方法以及不同口音和拼音的近似发音。同时提供了一些例子来说明这些策略的应用。 ... [详细]
  • loader资源模块加载器webpack资源模块加载webpack内部(内部loader)默认只会处理javascript文件,也就是说它会把打包过程中所有遇到的 ... [详细]
  • CS231n简介详见CS231n课程笔记1:Introduction。本文都是作者自己的思考,正确性未经过验证,欢迎指教。作业笔记本部分实现的是Momentum,RMSProb, ... [详细]
author-avatar
mobiledu2502886217
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有