在PHP中,没有普遍意义上的静态变量。与Java、C++不同,PHP中的静态变量的存活周期仅仅是每次PHP的会话周期,所以注定了不会有Java或者C++那种静态变量。
静态变量在PHP中
在PHP中,静态变量的存在意义仅仅是在某个结构体中(方法或者类)中传递一个变量,其作用域在此文件内。
<em style="color:transparent">本@文来源[email protected]搞@^&代*@码网(</em><q>搞代gaodaima码</q>function test(){ static $var = 1; echo $var++.''; } test(); test(); test(); //OutPut //1 //2 //3
在函数test的三次调用中,变量$var在三次调用中都是存在的,并且每次会递增1,而并没有清空或者重置
所以可以得出一个结论,静态变量在当前结构体所在的生命周期中一直存在。当前的例子中,test函数的生命周期就是当前PHP脚本,只要程序没释放都是有效的。
静态变量在类中
而在类中,代码大概是这样子的
class A { private static $a = 1; private $b = 2; public function add() { echo self::$a++.''; echo $this->b++.''; } } $class1 = new A(); $class1->add(); $class1->add(); $class2 = new A(); $class2->add(); $class2->add(); //Output //1 //2 //2 //3 //3 //2 //4 //3
从上面的类的运行结果来看,也得到了在函数中相同的结果
那么大概总结一下就是
PHP的静态变量在所在对应的结构体的生命周期中永久存在,并且值保持一致,不论这个结构体被调用或者实例化了多少次。
其实这就是动态变量和静态变量的区别,具体看此篇文章。动态变量只在类中有效,而静态变量在当前php脚本。
静态变量在单例模式中
再反过来看单例模式
class A { private static $instance = null; private $b = 1; public static function get_instance() { if(self::$instance == null){ $classname = __CLASS__; self::$instance = new $classname(); } return self::$instance; } public function add() { $this->b++; } public function show() { echo $this->b; } } $a = A::get_instance(); $b = A::get_instance(); //此处$a和$b变量完全相同! $a->add(); $a->show(); echo ''; $b->show(); //output //2 //2
此时,由于单例模式存在,使得$a和$b完全是同一个对象,所以之间如果需要共享数据,完全不需要静态变量(废话,就是自己。因为在任何时候,应用程序中都只会有这个类仅有的一个实例存在!无论你调用多少次单例,里面的数据是不会被重新实例化的。)
所以,在单例模式中,静态变量根本就没有存在的意义。当然,如果你没事干,非要使用new方法来初始化对象的话,也行,此时单例模式被打破,回归到无单例模式的状态。
如果为了防止使用new来实例化对象,那么可以考虑对类的__construct函数设置为private属性
class A { private static $instance = null; private $b = 1; private function __construct() { //Code in this function //could not be get out of the class } public static function get_instance() { if(self::$instance == null){ $classname = __CLASS__; self::$instance = new $classname(); } return self::$instance; } public function add() { $this->b++; } public function show() { echo $this->b; } } $a = A::get_instance(); $b = A::get_instance(); //此处$a和$b 变量完全相同! $a->add(); $a->show(); echo ' '; $b->show(); //output //2 //2 //如果尝试用new来实例化的话 $c = new A(); //output //Fatal error: Call to private A::__construct() from invalid context in //如果需要A类的实例化对象,只能通过开放的get_instance静态方法进行初始化