博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入理解PHP原理之变量作用域(Scope in PHP)
阅读量:4120 次
发布时间:2019-05-25

本文共 1235 字,大约阅读时间需要 4 分钟。

我前面的文章()介绍了PHP变量的内部表示,但是,问题是,这些内部表示是如何和用户脚本中的变量联系起来的呢?也就是说,如果我在脚本中写下:

ZE是如何把我的变量var和内部结构zval联系起来的呢?

深入理解PHP原理之变量中讲过,PHP内部都是使用zval来表示变量的,但是对于上面的脚本,我们的变量是有名字的, var。而zval中并没有相应的字段来体现变量名。

如果你想到了PHP内部一定有一个机制,来实现变量名到zval的映射。那么你真的是很聪明,;)

在PHP中,所有的变量都会存储在一个数组中(确切的说是hash table), 并且,PHP也是通过不同的数组来实现变量的作用域的。

当你创建一个变量的时候,PHP会为这个变量分配一个zval,填入相应的变量值,然后将这个变量的名字,和指向这个zval的指针填入一个数组中。然后,当你获取这个变量的时候,PHP会通过查找这个数组,获得对应的zval。

查看_zend_executor_globals结构(这个结构在PHP的执行器保存一些执行相关的上下文信息)

struct _zend_executor_globals {      ....    HashTable *active_symbol_table;/*活动符号表*/    HashTable symbol_table;     /*全局符号表*/     HashTable included_files;        jmp_buf *bailout;    int error_reporting;     .....}

其中,全局符号表,保存了在顶层作用域(就是不在任何函数,对象内)的变量。每当调用一个函数(对象的方法)的时候,就会为这个函数创建一个活动符号表,所有在这个函数内定义的变量,都会保存在这个活动符号表中。

对,这就是PHP的变量作用域的实现方式! 举个列子:

在函数sample外面的变量$var,它会被填入全局符号表中,与他对应的有一个zval指针,这个zval保存了一个字符串”I am in the global symbol table”.

函数内的$var, 它会被填入属于函数sample的活动符号表中,一样的,与他对应的zval中,保存着字符串”I am in the active symbol table
“.
比较特殊的,就是函数sample的参数$para了,这个$para是保存在sample的活动符号表的,但是与他对应的zval指针,会指向一个保存一份全局变量$var的copy的zval(严格来讲不是copy,是引用,这个涉及到变量的copy on write机制,我会在以后介绍)。

我们都知道PHP对于简单变量是传值调用的,但是,我要告诉你的是,PHP并不是简单的通过复制一个zval来实现传值的,呵呵,留个悬念,等我下回分解.

你可能感兴趣的文章
关于无线PCB中 中50欧姆的特性阻抗的注意事项
查看>>
Spring的单例模式源码小窥
查看>>
后台服务的变慢排查思路(轻量级应用服务器中测试)
查看>>
MySQL中InnoDB事务的默认隔离级别测试
查看>>
微服务的注册与发现
查看>>
bash: service: command not found
查看>>
linux Crontab 使用 --定时任务
查看>>
shell编程----目录操作(文件夹)
查看>>
机器学习-----K近邻算法
查看>>
HBASE安装和简单测试
查看>>
关于程序员的59条搞笑但却真实无比的编程语录
查看>>
搞笑--一篇有趣的文章编译自一篇西班牙博客。有一位美丽的公主,被关押在一个城堡中最高的塔上,一条凶恶的巨龙看守着她,需要有一位勇士营救她…
查看>>
非常不错 Hadoop 的HDFS (Hadoop集群(第8期)_HDFS初探之旅)
查看>>
Tomcat启动错误,端口占用
查看>>
laravel 修改api返回默认的异常处理
查看>>
高德坐标转换百度坐标 javascript
查看>>
tp5封装通用的修改某列值
查看>>
laravel控制器与模型名称不统一
查看>>
vue登录拦截
查看>>
npm配置淘宝镜像仓库以及electron镜像
查看>>