PHP static关键字用来定义静态方法及属性,在类中可用来延迟静态绑定以及在函数中修饰变量。 
 
1:先来谈谈static在函数中的用法; 
 function add(){ 
 
    static $a = 0; 
 
    echo $a," 
 "; 
 
    $a++; 
 
} 
 
这里static的作用即类似于C里的static的作用,保证$a变量只有在add()第一次调用时才会被初始化,但需要注意的是定义static变量的时候,可以不赋初值,可以给定初值,但是赋初值的时候不能使用表达式或者调用函数赋值,否则会报错。 
另外一点需要注意的即是static变量不会存储引用,如下:
 function get_obj_ref(){ 
 
     static $obj = null; 
 
     echo 'Ststic obj:'," 
 "; 
 
     var_dump($obj); 
 
     if(is_null($obj)){ 
 
         $obj = &new stdClass(); 
 
     } 
 
     return $obj; 
 } 
 
 $obj = get_obj_ref(); 
 
 $obj2 = get_obj_ref(); 
 function get_obj_noref(){ 
 
     static $obj = null; 
 
     echo 'Ststic obj:'," 
 "; 
 
     var_dump($obj); 
 
     if(is_null($obj)){ 
 
         $obj = new stdClass(); 
 
     } 
 
     return $obj; 
 
 } 
 
 $obj = get_obj_noref(); 
 
 $obj2 = get_obj_noref(); 
 
当static存储引用时,二次调用函数后,该变量的值并未被保存下来,且运行上面程序会报Deprecated错误,即返回引用值赋值的用法已弃。 
2:static在类中的延迟静态绑定;
延迟静态绑定是指允许在一个静态继承的上下文中引用被调用类。延迟绑定的意思为:static::不再为定义当前方法所在的类,而是实际运行时所在的类。注:它可以用于(但不限于)静态方法的调用。
除了简单的static延迟绑定的用法,还有一种转发调用,即使用self::,parent::,static:: 以及forward_static_call()(该函数只能在方法中调用)将转发调用信息,如下:
 class A { 
 
    public static function foo() { 
 
        static::who(); 
 
    } 
public static function who() {
    echo __CLASS__."\n";
}}
 class B extends A { 
 
    public static function test() { 
 
        A::foo(); 
 
        parent::foo(); 
 
        self::foo(); 
 
    } 
public static function who() {
    echo __CLASS__."\n";
} } 
 
class C extends B { 
 
    public static function who() { 
 
        echo CLASS."\n"; 
 
    } 
 
} 
 
C::test(); 
 
这里得到的结果是A C C,显然在调用parent::foo()时,还是使用了运行时调用类。 
 
还有一点需要注意的是:只有显示声明的static类才是从属与子类的。 
以下部分内容参考此博文:点击打开链接:PHP static 继承
 class A {    protected static $var1 = null;    protected static $var2 = null;    public static function test(){       if(!static::$var2){            static::$var2 = static::$var1;       }       echo get_called_class().' '.static::$var2.' ';    }  }  class B extends A {    protected static $var1 = 'b';    }  class C extends A {    protected static $var1 = 'c';    }  B::test();  C::test();  
  这里得到的结果是 b b。这里B类首先调用过test()方法,调用后$var2变量已经被赋值,而C类未定义自己的$var2变量,且父类中$var2变量值已经存在,故直接使用,若在B C类中显示定义$var2变量,则结果又会有所不同。 
  ———————————————— 
  原文链接:https://blog.csdn.net/bloodperfect/article/details/52416837 
