众所周知,在PHP的函数中,如果想使用全局变量,一种是使用超全局变量$GLOBALS,另一种是在函数中使用global关键字声明,使用超全局变量$GLOBALS的方式大家都知道了,今天来好好聊一聊使用global方式来声明变量。

我们来看如下例子:

$a = 1;
$b = 2;
function test() {
global $a, $b;
}
test();

当我们执行test()函数时,在内存中变量的状态是什么样的呢?如下图所示

我们声明了test函数,当调用test()函数时,global会在函数中声明两个局部变量$a, $b,并且分别指向全局变量$a和$b,此时的临时变量$a和$b相当于全局变量$a和$b的引用。所以我们在函数中修改局部变量$a和$b的值就等同于修改了全局变量的值。

$a = 1;
$b = 2;
function test() {
global $a, $b;
$a = 11;
$b = 12;
unset($a);
unset($b);
}
test();
echo $a;
echo '<br>';
echo $b;

浏览器上打印输出:

11
22

上面的代码中还使用了unset(),通过echo输出能输出全局变量$a, $b的值,这也说明test()函数里通过global关键字声明的$a和$b只是局部变量,unset()只是断开了局部变量与全局变量的引用。

我们来看另一种情况,如果我们在test函数中声明的变量在全局变量中并没有呢?

先说结论:如果在函数中使用global关键字声明的变量在全局作用域并没有同名变量,那么会先创建同名全局变量,再在函数中创建局部变量,同时将全局变量的引用指向局部变量。

function test() {
global $a, $b;
$a = 11;
$b = 22;
unset($a);
unset($b);
}
echo $a;
echo '<br>';
echo $b;

通过浏览器输出:

11
22

上面的代码,我们在test函数中使用global声明了变量$a, $b,虽然全局作用域并没有声明$a和$b,但是global依然会先创建全局变量$a和$b,然后在test函数中创建$a, $b,然后把全局变量的引用指向test函数的局部变量。所以即使我们在函数中unset了$a和$b,在函数执行完成后我们依然能打印出$a和$b,因为全局变量中已经存在着两个变量了。

所以我们最终可以对得出如下结论:

在函数中使用global声明变量时,会先在全局作用域查找是否有同名变量,如果有则将该全局变量的引用指向使用global声明的同名局部变量。如果全局作用域没有同名变量,那么就先创建同名全局变量,再创建局部变量,然后把全局变量的引用指向局部变量。

聊一聊PHP的global的更多相关文章

  1. 全局变量:global与$GLOBALS的区别和使用

    今天在写框架的时候想把SaeMySQL初始化之后作为全局变量使用.但是后来发现PHP中的全局变量和Java或者OC中的全局变量还是有较大区别的.下面记录一下php里面的global的使用相关注意事项. ...

  2. [翻译]ES 提案: global

    Jordan Harband 的 ECMAScript 提案“global”现在处于第三阶段.该提案提供了一种新的用于访问全局对象的标准方式. 全局对象的引用 下面是常用的几种引用全局对象的方式: 全 ...

  3. PHP中的全局变量global和$GLOBALS的区别

    1.global Global的作用是定义全局变量,但是这个全局变量不是应用于整个网站,而是应用于当前页面,包括include或require的所有文件. 但是在函数体内定义的global变量,函数体 ...

  4. 聊一聊PV和并发

    最近和几个朋友,聊到并发和服务器的压力问题.很多朋友,不知道该怎么去计算并发?部署多少台服务器才合适? 所以,今天就来聊一聊PV和并发,还有计算web服务器的数量 的等方法.这些都是自己的想法加上一些 ...

  5. 聊一聊log4j2配置文件log4j2.xml

    一.背景 最近由于项目的需要,我们把log4j 1.x的版本全部迁移成log4j 2.x 的版本,那随之而来的slf4j整合log4j的配置(使用Slf4j集成Log4j2构建项目日志系统的完美解决方 ...

  6. python中list作为全局变量无需global声明的原因

    发现一个问题. python中list变量作为全局变量时,在函数中可以直接修改. 而普通变量则需要先在函数中global声明,否则会报错. 例如: a = 1 def fun(): global a ...

  7. Global Translator

    Global Translator插件可以把已经通过翻译服务翻译好的内容生成对应语种的“静态”页面,或者说“缓存”起来,这样在一段时间内(可设置)想访问该语种的这 个页面的访客,就可以在不调用翻译服务 ...

  8. python 中使用 global 引发了莫名其妙的问题

    哪里出问题了 python 中,使用 global 会将全局变量设为本函数可用.同时,在函数内部访问变量会先本地再全局. 在嵌套函数中,使用 global 会产生不合常理的行为. 上代码: In [9 ...

  9. 通杀所有系统的硬件漏洞?聊一聊Drammer,Android上的RowHammer攻击

    通杀所有系统的硬件漏洞?聊一聊Drammer,Android上的RowHammer攻击 大家肯定知道前几天刚爆出来一个linux内核(Android也用的linux内核)的dirtycow漏洞.此洞可 ...

随机推荐

  1. Spring Scheduled定时任务报错 java.lang.IllegalStateException: Encountered invalid @Scheduled method 'xxx': For input string: "2S"

    报错信息如下: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ding ...

  2. java中实现对list的模糊查询

    比如我有下面这样一个List,里面存放的是多个Employee对象.然后我想对这个List进行按照Employee对象的名字进行模糊查询.有什么好的解决方案么?比如我输入的查询条件为“wang”,那么 ...

  3. linux(centos) tomcat设置开机启动

    亲测有效 环境: centos7 apache-tomcat-8.5.37 设置步骤: 1.修改/etc/rc.d/rc.local vi /etc/rc.d/rc.local 2.添加下面两行脚本, ...

  4. oracle 数据库去重复数据

    delete from 表名 a where rowid !=(select max(rowid) from 表名 b where a.ORDER_ID=b.ORDER_ID) 例:如果重复的数据表是 ...

  5. 面试简单整理之mybatis

    125.mybatis 中 #{}和 ${}的区别是什么? 1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号.如:order by #user_id#,如果传入的值是111,那么解 ...

  6. SQLPrompt 安装后sql上看不到菜单

    解决方案很简单,请使用管理员权限安装 破解也是一样,需要管理员权限运行

  7. 《修炼之道:.NET开发要点精讲》读书笔记(三)

    后几章的习题 1.异步调用开始后,什么时候才能使用异步执行的结果? A:最好在EndInvoke()方法返回之后才能使用异步执行的结果,其它时候不能保证异步调用已完成. 2.委托的异步调用开始后(即调 ...

  8. MyBatis中<if test=" ">标签条件不起作用

    问题产生? 今天在做Excel导出的时候,有个判断一个状态的字段,我的这个字段是int类型的,还有两个时间类型,我在判断的时候给的是Long类型的. 在测试的时候发现,不管怎么样都不执行if条件里面的 ...

  9. Effective C++ 笔记:条款 33 避免继承导致的名称遮掩

    Avoid hiding inherited names 作用域(scopes)所带来的名称二义性,c++编译器会寻找指涉(refer to)的对象并实现名称遮掩规则(name-hiding rule ...

  10. Redis详细讲解(Redis原理,Redis安装,Redis配置,Redis使用,Redis命令)

    一.Redis介绍 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发 ...