深入理解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实现12306余票查询、价格查询示例
Apr 17 PHP
PHP编译安装中遇到的两个错误和解决方法
Aug 20 PHP
Yii实现MySQL多数据库和读写分离实例分析
Dec 03 PHP
THINKPHP2.0到3.0有哪些改进之处
Jan 04 PHP
php实现遍历目录并删除指定文件中指定内容
Jan 21 PHP
PHP中使用imagick实现把PDF转成图片
Jan 26 PHP
为百度UE编辑器上传图片添加水印功能
Apr 16 PHP
php curl 获取https请求的2种方法
Apr 27 PHP
ThinkPHP实现附件上传功能
Apr 27 PHP
Laravel Intervention/image图片处理扩展包的安装、使用与可能遇到的坑详解
Nov 14 PHP
浅谈PHP SHA1withRSA加密生成签名及验签
Mar 18 PHP
PHP读取XML文件的方法实例总结【DOMDocument及simplexml方法】
Sep 10 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缓存设计实现代码
2011/09/30 PHP
php递归创建和删除文件夹的代码小结
2012/04/13 PHP
PHP+AJAX 投票器功能
2017/11/11 PHP
在laravel中实现将查询的对象转换为多维数组的函数
2019/10/21 PHP
基于jQuery的日期选择控件
2009/10/27 Javascript
javascript document.execCommand() 常用解析
2009/12/14 Javascript
javascript之bind使用介绍
2011/10/09 Javascript
JSON为什么那样红为什么要用json(另有洞天)
2012/12/26 Javascript
js获得页面的高度和宽度的方法
2014/02/23 Javascript
javascript设计简单的秒表计时器
2020/09/05 Javascript
jquery.cookie.js用法实例详解
2015/12/25 Javascript
JS调用Android、Ios原生控件
2017/01/06 Javascript
Angular2关于@angular/cli默认端口号配置的问题
2017/07/15 Javascript
Vue常见面试题整理【值得收藏】
2018/09/20 Javascript
javascript实现的时间格式加8小时功能示例
2019/06/13 Javascript
vue中实现图片压缩 file文件的方法
2020/05/28 Javascript
vue proxy 的优势与使用场景实现
2020/06/15 Javascript
Vue scoped及deep使用方法解析
2020/08/01 Javascript
express异步函数异常捕获示例详解
2020/11/30 Javascript
[03:07]2015国际邀请赛选手档案EHOME.rOtK 是什么让他落泪?
2015/07/31 DOTA
Cython 三分钟入门教程
2009/09/17 Python
pycharm 使用心得(二)设置字体大小
2014/06/05 Python
python写xml文件的操作实例
2014/10/05 Python
分享一个可以生成各种进制格式IP的小工具实例代码
2017/07/28 Python
python 删除指定时间间隔之前的文件实例
2018/04/24 Python
selenium + python 获取table数据的示例讲解
2018/10/13 Python
解决django后台样式丢失,css资源加载失败的问题
2019/06/11 Python
python Pandas库基础分析之时间序列的处理详解
2019/07/13 Python
Python三元运算与lambda表达式实例解析
2019/11/30 Python
HTML5新增属性data-*和js/jquery之间的交互及注意事项
2017/08/08 HTML / CSS
自考毕业自我鉴定范文
2013/10/27 职场文书
前台文员职责范本
2014/03/07 职场文书
机电专业求职信
2014/06/14 职场文书
教师个人培训总结
2015/02/11 职场文书
活动主持人开场白
2015/05/28 职场文书
浅谈Redis存储数据类型及存取值方法
2021/05/08 Redis