PHP学习之全局变量

PHP 的全局变量和 C 语言有一点点不同:在 C 语言中,全局变量在函数中自动生效,除非被局部变量覆盖。这可能引起一些问题,有些人可能不小心就改变了一个全局变量。因此PHP 中全局变量在函数中使用时必须声明为 global。

来看一下下面的这个例子:

<?php
$a = 1; /* global scope */

function Test()
{
    echo $a; /* reference to local scope variable */
}

Test();
?>

  

这个脚本不会有任何输出,因为 echo 语句引用了一个局部版本的变量 $a,而且在这个范围内,它并没有被赋值。

再看一个使用 global 的例子:

Example #1 使用 global

<?php
$a = 1;
$b = 2;

function Sum()
{
    global $a, $b;
    $b = $a + $b;
}

Sum();
echo $b;
?>

  

以上脚本的输出将是"3"。在函数中声明了全局变量 $a$b 之后,对任一变量的所有引用都会指向其全局版本。对于一个函数能够声明的全局变量的最大个数,PHP 没有限制。

在全局范围内访问变量的第二个办法,是用特殊的 PHP 自定义 $GLOBALS 数组。前面的例子可以写成:

Example #2 使用 $GLOBALS 替代 global

<?php
$a = 1;
$b = 2;

function Sum()
{
    $GLOBALS[‘b‘] = $GLOBALS[‘a‘] + $GLOBALS[‘b‘];
}

Sum();
echo $b;
?>

  

$GLOBALS 是一个关联数组,每一个变量为一个元素,键名对应变量名,值对应变量的内容。$GLOBALS 之所以在全局范围内存在,是因为 $GLOBALS 是一个超全局变量。以下范例显示了超全局变量的用处:

Example #3 演示超全局变量和作用域的例子

<?php
function test_global()
{
    // 大多数的预定义变量并不 "super",它们需要用 ‘global‘ 关键字来使它们在函数的本地区域中有效。
    global $HTTP_POST_VARS;

    echo $HTTP_POST_VARS[‘name‘];

    // Superglobals 在任何范围内都有效,它们并不需要 ‘global‘ 声明。Superglobals 是在 PHP 4.1.0 引入的。
    echo $_POST[‘name‘];
}
?>

  

全局变量的引用

请记住:如果在一个函数内部给一个声明为 global 的变量赋于一个引用,该引用只在函数内部可见。

在 Zend 引擎 1 代,它驱动了 PHP4,对于变量的 static 和 global 定义是以引用的方式实现的。例如,在一个函数域内部用 global 语句导入的一个真正的全局变量实际上是建立了一个到全局变量的引用。这有可能导致预料之外的行为,如以下例子所演示的:

<?php
function test_global_ref() {
    global $obj;
    $obj = &new stdclass;
}

function test_global_noref() {
    global $obj;
    $obj = new stdclass;
}

test_global_ref();
var_dump($obj);
test_global_noref();
var_dump($obj);
?>

  

以上例程会输出:

NULL
object(stdClass)(0) {
}

第一次输出NULL,原因是因为global $var; 是 $var =& $GLOBALS[‘var‘]; 的简写。从而将其它引用赋给 $var 只改变了本地变量$var的引用。
也就是说$obj = &new stdclass;这个语句改变了局部变量$obj的指向,global $obj 这句语句造成的效果已经被覆盖了。

 

类似的行为也适用于 static 语句。引用并不是静态地存储的:


<?php
function &get_instance_ref() {
    static $obj;

    echo ‘Static object: ‘;
    var_dump($obj);
    if (!isset($obj)) {
        // 将一个引用赋值给静态变量
        $obj = &new stdclass;
    }
    $obj->property++;
    return $obj;
}

function &get_instance_noref() {
    static $obj;

    echo ‘Static object: ‘;
    var_dump($obj);
    if (!isset($obj)) {
        // 将一个对象赋值给静态变量
        $obj = new stdclass;
    }
    $obj->property++;
    return $obj;
}

$obj1 = get_instance_ref();
$still_obj1 = get_instance_ref();
echo "\n";
$obj2 = get_instance_noref();
$still_obj2 = get_instance_noref();
?>

  


以上例程会输出:


Static object: NULL
Static object: NULL

Static object: NULL
Static object: object(stdClass)(1) {
["property"]=>
int(1)
}

 
时间: 2024-08-01 01:04:26

PHP学习之全局变量的相关文章

Ruby学习: 全局变量 和常量

一.全局变量 ruby中支持全局变量,ruby中的全局变量有如下几个特点: 1)标识符以$开头标记 2)全局变量可以在程序的任何地方加以引用 3)全局变量无需提前进行变量声明.引用尚未初始化的全局变量时,其值为 nil. 我们下面来看例子 class Demo def print puts $a end end puts $a #引用未声明的全局变量,$a这时值为nil demo = Demo.new demo.print #类方法中引用未声明的全局变量,$a这时值为nil $a=12 demo

Django学习之全局变量

首先说说什么叫全局变量,我们经常在html中使用{{ var }}这样的模板变量,这些变量是我们在视图函数中 提前定义好的变量,通过render()等方法传递到模板中. 但是,还有一类变量,我们并没有在views.py中定义,也能在html中使用该变量,像这样的变量,就叫做 全局变量. 下面来看看如何定义全局变量: 思路: 新建contexts.py文件-->修改settings.py文件-->在html中使用. 1.首先我们需要在项目根目录下的同名目录建立contexts.py文件 1 #!

蓝懿 2015 IOS 学习笔记 作用域 if判断 BOOL变量

我来自蓝懿教育 第二天学习了简单的计算器加减乘除的运算,变量,BOOL变量,以及if判断.掌握情况较为良好. 首先学习了简单计算器.在界面中输入两个添加数值的UITextview,在其中添加数字类型的数值,并且在下方有四个Button分别代表加减乘除,然后再放置两个Label作为符号显示与计算结果.图形是这样的: ————————随后学习的全局变量———————— 全局变量与局部变量的区别: 全局变量就是整个源程序都有效的变量:而局部变量会在其所属的函数或循环等结束后消亡.整个程序都要用的变量定

第二十四天到二十六天学习笔记

八号这天,主要先是学习了数组对象 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-cn">

solidity 0.5.7简明教程

以太坊不仅是一种加密数字货币,它更是功能完备的智能合约平台,solidity就是用来开发以太坊上的智能合约的原生开发语言.solidity最早发布于2015年,它是第一种图灵完备的智能合约专用开发语言.目前除了以太坊之外,在其他区块链中也逐渐开始支持solidity,例如hyperledger fabric.tendermint等.在这个solidity快速教程中,我们将使用最新0.5.7版的solidity,以一个具体的案例来介绍solidity智能合约的开发.部署与交互,希望对你快速掌握so

20191218《信息安全导论》第九周总结

教材学习内容总结 本周再次复习了冯诺依曼结构以及其核心存储结构体系:了解了计算机系统的构成框架:ALU.CU以及寄存器组成CPU,CPU和内存组成主机,虚拟内存和主机有构成进程:再一次体会到了计算机科学中抽象的重要性:同时,学习了一些基础Linus的操作指令:rm(删除),.(当前目录),..(上一目录),mkdir(创建文档),cd(更改文件目录),~(回到Home)等等:另外,学习了绝对路径(从根目录开始的目录)以及相对路径(从当前文件目录开始):区分设备文件与磁盘文件(文本文件与二进制文件

javascript学习笔记(二):定义函数、调用函数、参数、返回值、局部和全局变量

定义函数.调用函数.参数.返回值 关键字function定义函数,格式如下: function 函数名(){ 函数体 } 调用函数.参数.返回值的规则和c语言规则类似. 1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta chaset="UTF-8"> 5 <title></title> 6 </head> 7 <body

学习JavaScript之全局变量和隐式全局变量

隐式全局变量和明确定义的全局变量间有些小的差异,就是通过delete操作符让变量未定义的能力. 通过var创建的全局变量(任何函数之外的程序中创建)是不能被删除的. 无var创建的隐式全局变量(无视是否在函数中创建)是能被删除的. 这表明,在技术上,隐式全局变量并不是真正的全局变量,但它们是全局对象的属性.属性是可以通过delete操作符删除的,而变量是不能的: // 定义三个全局变量 var global_var = 1; global_novar = 2; // 反面教材 (function

python学习-day15:局部变量与全局变量、嵌套函数、递归

一.全局变量与局部变量 在子程序中定义的变量称为局部变量, 在程序的一开始定义的变量称为全局变量. 全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序.当全局变量与局部变量同名时:在定义局部变量的子程序内,局部变量起作用:在其它地方全局变量起作用. 通过在函数内部,先添加一个 global  name    相当于在子模块定义了一个全局变量.把局部的name扩到到全局变脸,后续name的变化,也是全局的! name='lhf' def change_name(): #global na