深入理解PHP原理之执行周期分析


Posted in PHP onJune 01, 2016

本文讲述了PHP原理之执行周期。分享给大家供大家参考,具体如下:

PHP的执行周期,从最初我们编写的PHP脚本->到最后脚本被执行->得到执行结果,这个过程,其实可以分为如下几个阶段:

首先,Zend Engine(ZE),调用词法分析 器(Lex生成的,源文件在 Zend/zend_language_sanner.l), 将我们要执行的PHP源文件,去掉空格 ,注释,分割成一个一个的token。

然后,ZE会将得到的token forward给语法分析 器(yacc生成, 源文件在 Zend/zend_language_parser.y),生成一个一个的opcode,opcode一般会以op array的形式存在,它是PHP执行的中间语言。

最后,ZE调用zend_executor来执行op array ,输出结果。(也就是将源文件转换成机器语言,然后在虚拟机上运行它。)

ZE是一个虚拟机,正是由于它的存在,所以才能使得我们写PHP脚本,完全不需要考虑所在的操作系统类型是什么,这才是PHP的可移植性的原因。ZE是一个CISC(复杂指令处理器),它支持150条指令(具体指令在 Zend/zend_vm_opcodes.h),包括从最简单的ZEND_ECHO(echo)到复杂的 ZEND_INCLUDE_OR_EVAL(include,require),所有我们编写的PHP都会最终被处理为这150条指令(op code)的序列,从而最终被执行

PHP是一个脚本语言,也就是说,用户编写的PHP代码最终都是会被PHP解释器解释执行,所有编写的PHP代码,都会被翻译成PHP的虚拟机ZE的虚拟指令(OPCODES)来执行。

那我们的PHP脚本,最终被“翻译"成什么样的呢? 也就是说,op code长的什么样子呢? Opcode是一种PHP脚本编译后的中间语言

在PECL中已经有这样的模块,利用由 Derick Rethans开发的VLD (Vulcan Logic Dissassembler)模块。你只要下载这个模块,并把他载入PHP中,就可以通过简单的设置,来得到脚本翻译的结果了。

VLD模块的安装以及应用:

[root@localhost software]# tar zxvf vld-0.9.1.tgz.gz
[root@localhost vld-0.9.1]# /usr/local/php/bin/phpize
[root@localhost vld-0.9.1]# ./configure --with-php-config=/usr/local/php/bin/php-config
[root@localhost vld-0.9.1]# make install //不需要make

编辑php.ini文件并激活vld扩展。

实例:

创建一个文件,如:hello.php

<?php
  echo 'hello, world.';
?>

执行:

[root@localhost html]# /usr/local/php/bin/php -dvld.active=1 hello.php
Branch analysis from position: 0
Return found
filename:    /var/www/html/hello.php
function name: (null)
number of ops: 3
compiled vars: none
line   # op              fetch     ext return operands
-------------------------------------------------------------------------------
  2   0 ECHO                           'hello%2C+world.'
  4   1 RETURN                          1
     2* ZEND_HANDLE_EXCEPTION
hello, world.

看另一个:

[root@localhost html]# vi vld.php
<?php
  $i = "This is a string";
  //I am comments
  echo $i. ' that has been echoed on screen';
?>

执行:

[root@localhost html]# /usr/local/php/bin/php -dvld.active=1 vld.php
Branch analysis from position: 0
Return found
filename:    /var/www/html/vld.php
function name: (null)
number of ops: 5
compiled vars: !0 = $i
line   # op              fetch     ext return operands
-------------------------------------------------------------------------------
  3   0 ASSIGN                          !0, 'This+is+a+string'
  7   1 CONCAT                      ~1  !0, '+that+has+been+echoed+on+screen'
     2 ECHO                           ~1
 10  3 RETURN                          1
     4* ZEND_HANDLE_EXCEPTION
This is a string that has been echoed on screen

注:ZEND_HANDLE_EXCEPTION 就是 Zend/zend_vm_opcodes.h 中第149条指令

compiled vars:  !0 = $i  此处是获取变量名"i"的变量于!0(*zval)。
#0 将字符串"this+is+a+string"赋值(ASSIGN)给!0
#1 字符串连接
#2 显示

这些中间代码会被Zend VM(Zend虚拟机)直接执行。真正负责执行的函数是:zend_execute(zend_execute.h)。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP产生随机字符串函数
Dec 06 PHP
PHP parse_url 一个好用的函数
Oct 03 PHP
php xml 入门学习资料
Jan 01 PHP
ThinkPHP多表联合查询的常用方法
Mar 24 PHP
Yii查询生成器(Query Builder)用法实例教程
Sep 04 PHP
PHP中实现接收多个name相同但Value不相同表单数据实例
Feb 03 PHP
codeigniter中view通过循环显示数组数据的方法
Mar 20 PHP
注释PHP和html混合代码的小技巧(分享)
Nov 03 PHP
phalcon model在插入或更新时会自动验证非空字段的解决办法
Dec 29 PHP
PHP正则判断一个变量是否为正整数的方法
Feb 27 PHP
Yii框架 session 数据库存储操作方法示例
Nov 18 PHP
让whoops帮我们告别ThinkPHP6的异常页面
Mar 02 PHP
深入理解PHP之OpCode原理详解
Jun 01 #PHP
深入理解PHP中的count函数
May 31 #PHP
Ubuntu server 11.04安装memcache及php使用memcache来存储session的方法
May 31 #PHP
php中json_encode不兼容JSON_UNESCAPED_UNICODE的解决方案
May 31 #PHP
让你的PHP7更快之Hugepage用法分析
May 31 #PHP
PHP表单数据写入MySQL数据库的代码
May 31 #PHP
PHP将页面中点击数量高的链接进行高亮显示的方法
May 30 #PHP
You might like
PHP时间戳使用实例代码
2008/06/07 PHP
php 获取一个月第一天与最后一天的代码
2010/05/16 PHP
PHP url 加密解密函数代码
2011/08/26 PHP
PHP搭建大文件切割分块上传功能示例
2017/01/04 PHP
有一段有意思的代码-javascript现实多行信息
2007/08/26 Javascript
jquery实现心算练习代码
2010/12/06 Javascript
jquery设置text的值示例(设置文本框 DIV 表单值)
2014/01/06 Javascript
jQuery制作拼图小游戏
2015/01/12 Javascript
javascript中的previousSibling和nextSibling的正确用法
2015/09/16 Javascript
jQuery获取与设置iframe高度的方法
2016/08/01 Javascript
微信小程序 教程之数据绑定
2016/10/18 Javascript
深入理解javascript的getTime()方法
2017/02/16 Javascript
Angular.js与node.js项目里用cookie校验账户登录详解
2017/02/22 Javascript
jQuery鼠标悬停内容动画切换效果
2017/04/27 jQuery
JS实现的类似微信聊天效果示例
2019/01/29 Javascript
怎样使你的 JavaScript 代码简单易读(推荐)
2019/04/16 Javascript
vue中使用GraphQL的实例代码
2019/11/04 Javascript
[56:42]VP vs RNG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
在Python中使用M2Crypto模块实现AES加密的教程
2015/04/08 Python
python email smtplib模块发送邮件代码实例
2018/04/26 Python
Python使用pymongo模块操作MongoDB的方法示例
2018/07/20 Python
Python实现按逗号分隔列表的方法
2018/10/23 Python
python随机模块random的22种函数(小结)
2020/05/15 Python
python_matplotlib改变横坐标和纵坐标上的刻度(ticks)方式
2020/05/16 Python
详解python如何引用包package
2020/06/07 Python
浅谈TensorFlow中读取图像数据的三种方式
2020/06/30 Python
基于python实现操作git过程代码解析
2020/07/27 Python
实现CSS3中的border-radius(边框圆角)示例代码
2013/07/19 HTML / CSS
电大物流学生的自我评价
2013/10/25 职场文书
专业实习自我鉴定
2013/10/29 职场文书
师范教师毕业鉴定
2014/01/13 职场文书
车队司机自我鉴定
2014/03/02 职场文书
学习与创新自我评价
2015/03/09 职场文书
留学推荐信中文范文
2015/03/26 职场文书
花木兰观后感
2015/06/10 职场文书
golang 在windows中设置环境变量的操作
2021/04/29 Golang