转载自longlong's blog
在PHP中,没有普遍意义上的静态变量。与Java、C++不同,PHP中的静态变量的存活周期仅仅是每次PHP的会话周期,所以注定了不会有Java或者C++那种静态变量。
所以,在PHP中,静态变量的存在意义仅仅是在某个结构体中(方法或者类)中传递一个变量。
看个例子好了
- <?php
- function test(){
- static $var = 1;
- echo $var++.'<br />';
- }
- test();
- test();
- test();
- //OutPut
- //1
- //2
- //3
- ?>
在函数test的三次调用中,变量$var在三次调用中都是存在的,并且每次会递增1,而并没有清空或者重置
所以可以得出一个结论,静态变量在当前结构体所在的生命周期中一直存在。当前的例子中,test函数的生命周期就是当前PHP脚本(好像所有的都是吧!)
而在类中,代码大概是这样子的
- <?php
- class A
- {
- private static $a = 1;
- private $b = 2;
- public function add()
- {
- echo self::$a++.'<br />';
- echo $this->b++.'<br />';
- }
- }
- $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 '<br />';
- $b->show();
- //output
- //2
- //2
此时,由于单例模式存在,使得$a和$b完全是同一个对象,所以之间如果需要共享数据,完全不需要静态变量(废话,就是自己!)
所以,在单例模式中,静态变量根本就没有存在的意义。当然,如果你没事干,非要使用new方法来初始化对象的话,也行,此时单例模式被打破,回归到无单例模式的状态。
如果为了防止使用new来实例化对象,那么可以考虑对类的__construct函数设置为private属性
- <?php
- 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 '<br />';
- $b->show();
- //output
- //2
- //2
//如果尝试用new来实例化的话
$c = new A();
//output
//Fatal error: Call to private A::__construct() from invalid context in
//如果需要A类的实例化对象,只能通过开放的get_instance静态方法进行初始化
转载于:https://blog.51cto.com/superfly81/1093087