PHP static 静态变量的作用域

󰃭 2016-09-04

static

在PHP中,static 表示静态, 包括了静态属性静态变量静态方法(函数), 又或者可用来表示类的延迟加载

不过今天不说这个, 而是尝试去说明static静态变量作用域

理解

static 变量的作用域常规的理解是全局有效的。

那么怎么去理解这个全局的概念,我的理解如下

  1. 不管类被实例化还是直接静态调用, 对静态变量的定义和修改都是对同一个变量的修改
  2. 不论是父类还是子类,甚至是抽象类,只要能访问到静态变量,访问的都是同一个变量

实践

针对以上两点,做以下说明

针对第一点

不管类被实例化还是直接静态调用, 对静态变量的定义和修改都是对同一个变量的修改

这个比较直接,一般都不会混淆

 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的一个静态变量, 和上面我们的常规类和对象中的一样

以上,针对疑惑做的一个记录