PHP static 静态变量的作用域
2016-09-04
static
在PHP中,static
表示静态
, 包括了静态属性
,静态变量
和静态方法(函数)
,
又或者可用来表示类的延迟加载
不过今天不说这个, 而是尝试去说明static
的静态变量作用域
理解
static
变量的作用域常规的理解是全局有效的。
那么怎么去理解这个全局
的概念,我的理解如下
- 不管类被实例化还是直接静态调用, 对静态变量的定义和修改都是对同一个变量的修改
- 不论是父类还是子类,甚至是抽象类,只要能访问到静态变量,访问的都是同一个变量
实践
针对以上两点,做以下说明
针对第一点
不管类被实例化还是直接静态调用, 对静态变量的定义和修改都是对同一个变量的修改
这个比较直接,一般都不会混淆
abstract class A
{
protected static $names=[];
//静态新增
abstract public static function add_name($name);
//常规新增
abstract public function dadd_name($name);
public function get_names()
{
return static::$names;
}
public static function pop_name()
{
array_pop(static::$names);
}
}
class CA extends A
{
// 抽象实现
public static function add_name($name)
{
static::$names[] = $name;
}
// 抽象实现
public function dadd_name($name)
{
static::$name[] = $name;
}
}
以上三个类,都能访问静态变量$names
我们以CA类
为例
$ca = new CA();
$ca->add_name("Tony");
CA::add_name("Wang");
var_dump(CA::get_names());
输出结果如下
array(2) {
[0]=>
string(4) "Tony"
[1]=>
string(4) "Wang"
}
可以看出,实例化的类和静态类对静态变量
的修改都是针对同一个变量的
针对第二点
受继承的关系的影响, 我一直认为静态变量中, 如果是子类对父类的静态变量做了修改, 父类是不可知的,即子类里的静态变量只是在子类做修改时有影响, 父类里的静态变量仅在父类做修改时有影响
这当然是错的, 实际上, 只要能访问到静态变量
, 对静态变量
的修改都是全局性的
,对抽象类的静态变量
也是如此
也是用上面的类
$ca = new CA();
$ca->add_name("Tony");
CA::add_name("Wang");
var_dump(A::get_names()); //["Tony","Wang"]
var_dump(CCA::get_names());//["Tony","Wang"]
无论是子类还是父类, 都能访问到该静态变量
,而且是同一个
再继续如下操作
A::pop_name();
var_dump(A::get_names()); //["Tony"]
var_dump(CCA::get_names());//["Tony"]
如上, 即便是抽象类对静态变量
的修改,都是针对同一个变量的
闭包函数中的static
在闭包函数
中,设置为static
的变量, 同上面一样都是全局性
的
$n = function (){
static $name;
if(is_null($name)){
var_dump("hello");
$name = "Tony";
}
return $name;
};
$n();
var_dump($n());
输出如下:
string(5) "hello"
string(4) "Tony"
重点是hello
仅仅被打印了一次, 说明第二次调用闭包函数时,$name
已经存在了
实际上, 闭包函数都是Closure
类的实例, 所以, static
的变量 也就就是Closure的一个静态变量
,
和上面我们的常规类和对象中的一样
以上,针对疑惑做的一个记录