搜索
首页php教程php手册PHP源码分析之Global关键字

 

  闲来无事,就系统的从PHP的词法分析,语法分析,opcodes生成,执行,整个流程,详细的分析了global关键字的实现。

  当你在脚本中写下:

 

  

  $var = "laruence";

  function sample(){

  global $var;

  }

  ?>

 

  的时候,你知道PHP是怎么实现在函数作用域找到全局变量的么?

  在我前面的文章中(深入理解PHP原理之Opcodes)讲过, PHP的执行,经历了如下几个阶段:

 

  1. Scanning(Lexing) ,将PHP代码转换为语言片段(Tokens)

  2. Parsing, 将Tokens转换成简单而有意义的表达式

  3. Compilation, 将表达式编译成Opocdes

  4. Execution, 顺次执行Opcodes,每次一条,从而实现PHP脚本的功能。

 

  那么,第一阶段,自然就是Scanning了, 在词法分析阶段,我们的

 

  global $var;

 

  会被解析为:

 

  T_GLOBAL var;

 

  接下来是parsing阶段:

 

  T_GLOBAL var;

 

  yacc经过规则:

 

  statement:

   T_GLOBAL global_var_list ';'

  ....

  global_var_list:

  global_var_list ',' global_var { zend_do_fetch_global_variable(&$3, NULL, ZEND_FETCH_GLOBAL_LOCK TSRMLS_CC); }

   global_var { zend_do_fetch_global_variable(&$1, NULL, ZEND_FETCH_GLOBAL_LOCK TSRMLS_CC); }

  ;

 

  其中, zend_do_fetch_global_variable是真正生成opcode的函数:

 

  zend_op *opline;

  ......

  opline->opcode = ZEND_FETCH_W;

  opline->result.op_type = IS_VAR;

  ......

  opline->op2.u.EA.type = ZEND_FETCH_GLOBAL_LOCK;

 

  而对于ZEND_FETCH_W的op_handler是:

  ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONSTTMPVARCV, ANY) { ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_W); }

  我们来看看zend_fetch_var_adress_helper:

  ..... target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), type, varname TSRMLS_CC);/* if (!target_symbol_table) { ZEND_VM_NEXT_OPCODE(); }*/ if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &retval) == FAILURE) { switch (type) { case BP_VAR_R: case BP_VAR_UNSET: zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname)); /* break missing intentionally */ case BP_VAR_IS: retval = &EG(uninitialized_zval_ptr); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname)); /* break missing intentionally */ case BP_VAR_W: { zval *new_zval = &EG(uninitialized_zval); new_zval->refcount++; zend_hash_update(target_symbol_table, varname->value.str.val, varname->value.str.len+1, &new_zval, sizeof(zval *), (void **) &retval); } break; EMPTY_SWITCH_DEFAULT_CASE() } }

  可以看出,核心就是zend_get_targer_symbol_table这个函数了:

  static inline HashTable *zend_get_target_symbol_table(zend_op *opline, temp_variable *Ts, int type, zval *variable TSRMLS_DC){ switch (opline->op2.u.EA.type) { case ZEND_FETCH_LOCAL: return EG(active_symbol_table); break; case ZEND_FETCH_GLOBAL: case ZEND_FETCH_GLOBAL_LOCK: return &EG(symbol_table); break; case ZEND_FETCH_STATIC: if (!EG(active_op_array)->static_variables) { ALLOC_HASHTABLE(EG(active_op_array)->static_variables); zend_hash_init(EG(active_op_array)->static_variables, 2, NULL, ZVAL_PTR_DTOR, 0); } return EG(active_op_array)->static_variables; break; EMPTY_SWITCH_DEFAULT_CASE() } return NULL;}

  恩,问题清楚了,也就是说, 如果你global了一个变量,那么Zend就会去全局symbol_table去寻找,如果找不到,就会在全局symbol_table中分配相应的变量。

  通过这样的机制,实现了全局变量。



声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
OOBELANGUAGE错误Windows 11 / 10修复中出现问题的问题OOBELANGUAGE错误Windows 11 / 10修复中出现问题的问题Jul 16, 2023 pm 03:29 PM

您是否在Windows安装程序页面上看到“出现问题”以及“OOBELANGUAGE”语句?Windows的安装有时会因此类错误而停止。OOBE表示开箱即用的体验。正如错误提示所表示的那样,这是与OOBE语言选择相关的问题。没有什么可担心的,你可以通过OOBE屏幕本身的漂亮注册表编辑来解决这个问题。快速修复–1.单击OOBE应用底部的“重试”按钮。这将继续进行该过程,而不会再打嗝。2.使用电源按钮强制关闭系统。系统重新启动后,OOBE应继续。3.断开系统与互联网的连接。在脱机模式下完成OOBE的所

如何修复Windows服务器中的激活错误代码0xc004f069如何修复Windows服务器中的激活错误代码0xc004f069Jul 22, 2023 am 09:49 AM

Windows上的激活过程有时会突然转向显示包含此错误代码0xc004f069的错误消息。虽然激活过程已经联机,但一些运行WindowsServer的旧系统可能会遇到此问题。通过这些初步检查,如果这些检查不能帮助您激活系统,请跳转到主要解决方案以解决问题。解决方法–关闭错误消息和激活窗口。然后,重新启动计算机。再次从头开始重试Windows激活过程。修复1–从终端激活从cmd终端激活WindowsServerEdition系统。阶段–1检查Windows服务器版本您必须检查您使用的是哪种类型的W

在Vue应用中使用axios时出现“TypeError: Failed to fetch”怎么办?在Vue应用中使用axios时出现“TypeError: Failed to fetch”怎么办?Jun 24, 2023 pm 11:03 PM

最近,在使用Vue应用开发过程中,我遇到了一个常见的问题:“TypeError:Failedtofetch”错误提示。这个问题出现在使用axios进行HTTP请求时,后端服务器没有正确响应请求时发生。这种错误提示通常表明请求无法到达服务器,可能是由于网络原因或服务器未响应造成的。出现这个错误提示后,我们应该怎么办呢?以下是一些解决方法:检查网络连接由于

如何在iPhone上提取RAR文件如何在iPhone上提取RAR文件Jul 12, 2023 pm 07:53 PM

很多时候,非常大的文件很难在设备之间共享,尤其是智能手机等。因此,这些文件首先被存档/压缩成RAR文件,然后发送到另一个设备进行共享。但问题是RAR文件不容易在iPhone上提取。要提取zip文件,只需轻点一下即可。没有多少人知道在iPhone上提取RAR文件的过程,对于初学者来说,这些步骤可能会令人困惑。可以使用iPhone上称为快捷方式的默认应用程序来完成此操作。我们在这里逐步解释了如何使用快捷方式应用程序在iPhone上提取任何RAR文件。如何在iPhone上提取RAR文件步骤1:首先,您

在 Windows 3 上禁用透明效果的 11 种快速方法在 Windows 3 上禁用透明效果的 11 种快速方法Sep 06, 2023 pm 04:13 PM

透明效果增强了Windows11的视觉吸引力,尤其是任务栏、“开始”菜单和登录屏幕。但我们都有不同的偏好。对于那些不喜欢它的人来说,在Windows11中禁用透明度效果不会花费太多时间。禁用后,背景颜色不会影响操作系统组件的配色方案,并且会采用相当不透明的形式。此外,以下是在Windows11中禁用透明度效果的主要好处:Windows11中的透明度效果可能会影响性能并降低旧电脑的速度。功耗增加,电池寿命缩短,但在大多数情况下并不明显。动画感觉更流畅、更无缝。如何在Windows11上关闭透明效果

Windows 事件日志禁用教程:简单步骤Windows 事件日志禁用教程:简单步骤Aug 14, 2023 am 09:49 AM

事件日志是详细说明主要和次要更改甚至错误的报告。如果服务或启动应用在第一次尝试时无法运行,则会生成日志。但是,当日志数量变得很大时,用户可能希望禁用Windows事件日志。单个日志在磁盘上占用的空间很小,但如果每天生成数千个此类报告并将其存储在SSD上,那么您会看到性能下降。继续阅读以了解如何在Windows中关闭事件日志记录!是否可以禁用Windows事件日志?是的,禁用事件日志没有坏处。请记住,这些日志只是有助于解决问题的报告。他们不执行任何操作或自动解决手头的问题。对于许多用户来说,令人惊

Windows 11/10 修复中缺少本地安全机构 (LSA) 选项Windows 11/10 修复中缺少本地安全机构 (LSA) 选项Jul 07, 2023 pm 12:49 PM

Windows安全中心应用中缺少本地安全机构(LSA)选项背后的可能原因可能是Windows安全中心主要组件损坏。有时,如果你有一段时间没有更新系统,Windows安全中心的定义可能会变得非常过时。这些是应该可以帮助您找回缺失部分的解决方案。修复1–手动创建RunAsPPL密钥创建RunAsPPL键和后续值以修复Windows安全中心中的LSA问题。注意–注册表编辑并非易事。有时,这些编辑可能会出错并且可能很危险。因此,请备份注册表文件,以便以后可以使用。步骤1–您只需要在框中输入“注册表”并按

如何在Zend框架中使用ACL(Access Control List)进行权限控制如何在Zend框架中使用ACL(Access Control List)进行权限控制Jul 29, 2023 am 09:24 AM

如何在Zend框架中使用ACL(AccessControlList)进行权限控制导言:在一个Web应用程序中,权限控制是至关重要的一项功能。它可以确保用户只能访问其有权访问的页面和功能,并防止未经授权的访问。Zend框架提供了一种方便的方法来实现权限控制,即使用ACL(AccessControlList)组件。本文将介绍如何在Zend框架中使用ACL

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),