PHP 变量作用域


局部和全局作用域、global 关键字、static 作用域、参数作用域、define/const常量、超级全局变量、魔术常量、域运算符、 this、self、parent 等


正文

php 变量都有作用域,下面总结下,以备以后查询。

四种不同的变量作用域:local、global、static、parameter

局部作用域和全局作用域

全局作用域:在所有函数外部定义的变量,拥有全局作用域。除了函数外,全局变量可以被脚本中的任何部分访问, 不过要注意赋值顺序,只有变量被赋值后才能在接下来代码中被访问到; 要在一个函数中访问一个全局变量,需要使用 global 关键字,也可以使用$GLOBALS[index]方式访问。

局部作用域:在 PHP 函数内部声明的变量是局部变量,仅能在函数内部访问。

global 关键字

global 关键字用于函数内访问全局变量。

在函数内调用函数外定义的全局变量,我们需要在函数中的变量前加上 global 关键字。

PHP 将所有全局变量存储在一个名为 $GLOBALS[index] 的数组中。 index 保存变量的名称。 这个数组可以在函数内部访问,也可以直接用来更新全局变量。

$x = 75; 
$y = 25;
 
function addition() 
{ 
    $GLOBALS['z'] = $GLOBALS['x'] + $GLOBALS['y']; 
    global $x;
    echo $x;  // 75
    echo PHP_EOL;
}
 
addition(); 
echo $z;  // 100 

static 作用域

当一个函数完成时,它的所有变量通常都会被删除。然而,有时候您希望某个局部变量不要被删除。

要做到这一点,请在您第一次声明变量时使用 static 关键字:

function myTest()
{
    static $x=0;
    echo $x;
    $x++;
    echo PHP_EOL;    // 换行符
}
 
myTest();  // 0
myTest();  // 1
myTest();  // 2

然后,每次调用该函数时,该变量将会保留着函数前一次被调用时的值。

注意:该变量仍然是函数的局部变量。外部无法访问到。

参数作用域

参数是通过调用代码将值传递给函数的局部变量。

参数是在参数列表中声明的,作为函数声明的一部分:

function myTest($x)
{
    echo $x;
}
myTest(5);

define常量

这里提一下常量,看一下使用方法。

常量是一个简单值的标识符。常量值被定义后,在脚本的其他任何地方都不能被改变。

一个常量由英文字母、下划线、和数字组成,但数字不能作为首字母出现。 (常量名不需要加 $ 修饰符)。一般开发中常用大写字母组成常量。

设置 PHP 常量,使用 define() 函数,函数语法如下:

bool define ( string $name , mixed $value [, bool $case_insensitive = false ] )

该函数有三个参数:
name:必选参数,常量名称,即标志符。
value:必选参数,常量的值。
case_insensitive :可选参数,如果设置为 TRUE,该常量则大小写不敏感。默认是大小写敏感的。

常量在定义后,默认是全局变量,可以在整个运行的脚本的任何地方使用。

以下实例演示了在函数内使用常量,即便常量定义在函数外也可以正常使用常量。

define("GREETING", "欢迎");
 
function myTest() {
    echo GREETING;
}
 
myTest();    // 输出 "欢迎"

const常量

const、define异同比较:

使用const使得代码简单易读,const本身就是一个语言结构,而define是一个函数。另外const在编译时要比define快很多。

const用于类成员变量的定义,一经定义,不可修改。Define不可以用于类成员变量的定义,可用于全局常量。

const可在类中使用,define不能。

const不能在条件语句中定义常量。

const采用普通的常量名称,define可以采用表达式作为名称。

const只能接受静态的标量,而define可以采用任何表达式。

const定义的常量大小写敏感,而define可以通过第三个参数(为true表示大小写不敏感)来指定大小写是否敏感。

超级全局变量

PHP中预定义了几个超级全局变量(superglobals) ,这意味着它们在一个脚本的全部作用域中都可用。 你不需要特别说明,就可以在函数及类中使用。

PHP 超级全局变量列表:

$GLOBALS   // 超级全局变量组
$_SERVER   // 一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组
$_REQUEST  // HTML表单提交的数据
$_POST     // input 字段数据
$_GET      // URL中发送的数据
$_FILES    // 文件上传数据
$_ENV      // 通过环境方式传递给当前脚本的变量的数组
$_COOKIE   // cookie数据
$_SESSION  // session数据

魔术常量

__LINE__   // 文件中的当前行号
__FILE__   // 文件的完整路径和文件名
__DIR__    // 文件所在的目录,它等价于 dirname(__FILE__)
__FUNCTION__    // 返回该函数被定义时的名字(区分大小写)
__CLASS__       // 返回该类被定义时的名字(区分大小写)
__TRAIT__       // Trait 的名字
__METHOD__      // 类的方法名
__NAMESPACE__   // 当前命名空间的名称

域运算符

::,是域运算符,也叫作用域限定符。

在外部访问PHP类中的成员变量或方法时,如果被引用的变量或者方法被声明成const(定义常量)或者static(声明静态),那么就必须使用操作符::, 反之在外部访问PHP类中的成员变量或方法时,如果被引用的变量或者方法没有被声明成const或者static,那么就必须使用操作符->

另外,如果从类的内部访问const或者static变量或者方法,那么就必须使用自引用的self, 反之如果从类的内部访问不为const或者static变量或者方法,那么就必须使用自引用的$this

可以在 :: 操作符的左边写上类的名称来静态地访问某个成员,这样避免创建类的实例。 不仅省略掉实例化类的代码, 而且还会更高效, 因为类的每个实例都会占用一小部分的系统资源。

在使用 :: 操作符访问成员变量时, 需要再次注意对$符号的使用。 因为PHP当前不支持动态的静态变量的使用, 也就是说不支持可变的静态变量。 在使用$this->$var时, 被访问的成员是包含在$var中的变量的值。 而不用$符号访问某个变量实际上查找的是类的某个常量,而常量是不能通过$this来访问的。

在类里面的时候,$this->func()self::func()没什么区别。 在外部的时候,->必须是实例化后的对象使用; 而::可以是未实例化的类名直接调用。

this

this是指向当前对象的指针,也就是class类new实例化后的对象,是对象的资源。

$this 只表示类的当前实例, 而 self:: 表示的是类本身。

self

self是指向当前类的指针,是类的资源。

self是指向类本身,也就是self是不指向任何已经实例化的对象,一般self使用来指向类中的静态变量。

parent

parent是指向父类的指针,是类的资源。

在扩展类中, 在基类的方法被重写的情况下,使用 parent 作用域调用定义在基类中的方法。 静态成员也可以只属于父类。 如果在子类和父类中同时声明了某个成员,也可以使用parant:: 在子类中访问父类中的变量, 在这种情况下, 父类的静态成员和子类的静态成员保存的是不同的值。






参考资料

PHP 变量 https://www.runoob.com/php/php-variables.html

PHP 常量 https://www.runoob.com/php/php-constants.html

PHP 常量语法 https://www.php.net/manual/zh/language.constants.syntax.php

PHP 超级全局变量 https://www.runoob.com/php/php-superglobals.html

PHP 文件上传 https://www.runoob.com/php/php-file-upload.html

$_ENV https://www.php.net/manual/zh/reserved.variables.environment.php

PHP 魔术常量 https://www.runoob.com/php/php-magic-constant.html

PHP常量详解:define和const的区别 https://www.cnblogs.com/zhouguowei/p/5199076.html

PHP中::、->、self、parent::、$this操作符的区别 https://www.cnblogs.com/hechunhua/p/3909574.html

PHP中this,self,parent三个关键字 https://www.cnblogs.com/moxiaoan/p/6228905.html


返回