单例模式与静态变量在PHP中

在PHP中,没有普遍意义上的静态变量。与Java、C++不同,PHP中的静态变量的存活周期仅仅是每次PHP的会话周期,所以注定了不会有Java或者C++那种静态变量。

所以,在PHP中,静态变量的存在意义仅仅是在某个结构体中(方法或者类)中传递一个变量,其作用域在此文件内。
看个例子好了

 1 function test(){
 2     static $var = 1;
 3     echo $var++.‘
 4 ‘;
 5 }
 6 test();
 7 test();
 8 test();
 9 //OutPut
10 //1
11 //2
12 //3

在函数test的三次调用中,变量$var在三次调用中都是存在的,并且每次会递增1,而并没有清空或者重置
所以可以得出一个结论,静态变量在当前结构体所在的生命周期中一直存在。当前的例子中,test函数的生命周期就是当前PHP脚本,只要程序没释放都是有效的。
而在类中,代码大概是这样子的

 1 class A
 2 {
 3     private static $a = 1;
 4     private $b = 2;
 5     public function add()
 6     {
 7         echo self::$a++.‘
 8 ‘;
 9         echo $this->b++.‘
10 ‘;
11     }
12 }
13 $class1 = new A();
14 $class1->add();
15 $class1->add();
16 $class2 = new A();
17 $class2->add();
18 $class2->add();
19 //Output
20 //1
21 //2
22 //2
23 //3
24 //3
25 //2
26 //4
27 //3

从上面的类的运行结果来看,也得到了在函数中相同的结果
那么大概总结一下就是
PHP的静态变量在所在对应的结构体的生命周期中永久存在,并且值保持一致,不论这个结构体被调用或者实例化了多少次。

其实这就是动态变量和静态变量的区别,具体看此篇文章。动态变量只在类中有效,而静态变量在当前php脚本。

再反过来看单例模式

 1 class A
 2 {
 3     private static $instance = null;
 4     private $b = 1;
 5     public static function get_instance()
 6     {
 7         if(self::$instance == null){
 8             $classname = __CLASS__;
 9             self::$instance = new $classname();
10         }
11         return self::$instance;
12     }
13     public function add()
14     {
15         $this->b++;
16     }
17     public function show()
18     {
19         echo $this->b;
20     }
21 }
22 $a = A::get_instance();
23 $b = A::get_instance();
24 //此处$a和$b 变量完全相同!
25 $a->add();
26 $a->show();
27 echo ‘
28 ‘;
29 $b->show();
30 //output
31 //2
32 //2

此时,由于单例模式存在,使得$a和$b完全是同一个对象,所以之间如果需要共享数据,完全不需要静态变量(废话,就是自己。因为在任何时候,应用程序中都只会有这个类仅有的一个实例存在!无论你调用多少次单例,里面的数据是不会被重新实例化的。)

所以,在单例模式中,静态变量根本就没有存在的意义。当然,如果你没事干,非要使用new方法来初始化对象的话,也行,此时单例模式被打破,回归到无单例模式的状态。

如果为了防止使用new来实例化对象,那么可以考虑对类的__construct函数设置为private属性

 1 class A
 2 {
 3     private static $instance = null;
 4     private $b = 1;
 5     private function __construct()
 6     {
 7     //Code in this function
 8     //could not be get out of the class
 9     }
10     public static function get_instance()
11     {
12         if(self::$instance == null){
13             $classname = __CLASS__;
14             self::$instance = new $classname();
15         }
16         return self::$instance;
17     }
18     public function add()
19     {
20         $this->b++;
21     }
22     public function show()
23     {
24         echo $this->b;
25     }
26 }
27 $a = A::get_instance();
28 $b = A::get_instance();
29 //此处$a和$b 变量完全相同!
30 $a->add();
31 $a->show();
32 echo ‘
33 ‘;
34 $b->show();
35 //output
36 //2
37 //2
38
39 //如果尝试用new来实例化的话
40 $c = new A();
41 //output
42 //Fatal error: Call to private A::__construct() from invalid context in
43 //如果需要A类的实例化对象,只能通过开放的get_instance静态方法进行初始化

优点:单例模式可以避免大量的new操作,因为每一次new操作都会消耗内存资源和系统资源

缺点:在PHP中,所有的变量无论是全局变量还是类的静态成员,都是页面级的,每次页面被执行时,都会重新建立新的对象,都会在页面执行完毕后被清空,这样似乎PHP单例模式就没有什么意义了,所以PHP单例模式我觉得只是针对单次页面级请求时出现多个应用场景并需要共享同一对象资源时是非常有意义的


文章来源:http://blog.chinaunix.net/uid-25979788-id-3220510.html

时间: 2024-08-02 04:28:20

单例模式与静态变量在PHP中的相关文章

单例模式与静态变量在PHP中 (转载)

在PHP中,没有普遍意义上的静态变量.与Java.C++不同,PHP中的静态变量的存活周期仅仅是每次PHP的会话周期,所以注定了不会有Java或者C++那种静态变量. 所以,在PHP中,静态变量的存在意义仅仅是在某个结构体中(方法或者类)中传递一个变量,其作用域在此文件内. 看个例子好了 function test(){ static $var = 1; echo $var++.'<br />'; } test(); test(); test(); //OutPut //1 //2 //3 在

[转]单例模式与静态变量在PHP中

在PHP中,没有普遍意义上的静态变量.与Java.C++不同,PHP中的静态变量的存活周期仅仅是每次PHP的会话周期,所以注定了不会有Java或者C++那种静态变量. 所以,在PHP中,静态变量的存在意义仅仅是在某个结构体中(方法或者类)中传递一个变量,其作用域在此文件内. 看个例子好了 1 2 3 4 5 6 7 8 9 10 11 function test(){ static $var = 1; echo $var++.'<br />'; } test(); test(); test()

内部类访问外部类的变量必须是final吗,java静态方法中不能引用非静态变量,静态方法中不能创建内部类的实例

内部类访问外部类的变量必须是final吗? 如下:class A{int i = 3;public void shout(){ class B{public void shout1(){System.out.println(i);} }B b=new B();b.shout1();} public static void main(String [] args){A a=new A();a.shout();} }可正常输出3,证明可以访问类的变量i,但改为下面的方式:class A{public

java中静态变量在内存中的位置

java程序在内存中的存储分配情况: 一.堆区: 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的目的是得到操作指令) 2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身 栈区: 1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中 2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问. 3.栈分为3个部分:基本类型变量区.执行环境上下文.操作指令区(存

静态变量和单例模式

静态变量和单例模式 1.静态变量 静态变量(Static Variable)在计算机编程领域指在程序执行前系统就为之静态分配(也即在运行时不再改变分配情况)存储空间的一类变量.与之相对应的是在运行时只暂时存在的自动变量(即局部变量)与以动态分配方式获取存储空间的一些对象,其中自动变量的存储空间在调用栈上分配与释放. 不同情况下的作用 除明确标识出变量的生命周期外,将变量声明为static存储类还会根据变量属性不同而有一些特殊的作用: 对于静态全局变量来说,针对某一源文件的以static声明的文件

Java中的静态变量static

package com.wangcf; public class Test { String name="你好"; static String sex="男"; Test t=new Test(); /** * 静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员 * 如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量 */ public static void print(){ Test test=new Test(

Qt中静态变量使用方法

静态变量可以在各个页面之前使用 先定义一个用于存放静态变量的类 例如datavar 在datavar.h中添加如下代码 #ifndef DATAVAR_H #define DATAVAR_H #include <QObject> class dataVar : public QObject { Q_OBJECT public: explicit dataVar(QObject *parent = 0); static QString loginName ;//登录名 signals: publ

静态变量和实例变量差别

JAVA类的成员变量有两种: 1.静态变量.被static修饰的变量,也叫类变量. 2.实例变量.没有static修饰的变量. 差别: 静态变量是共享的,在整个JVM中仅仅存在一个, 而成员变量是每个实例所独有的.供实例自己使用. 样例: 一个学生类:年龄.姓名,性别是实例变量.由于每一个人的年龄,姓名都可能不同. 而学费能够是类变量,每一个学生的学费基本都是一样的.(特殊的除外) 应用场景: 当一个对象是这个类全部实例所共享的时候,用类变量 假设每一个实例的值都可能不同.用实例变量. 静态变量

静态变量和实例变量区别

JAVA类的成员变量有两种: 1.静态变量,被static修饰的变量,也叫类变量. 2.实例变量,没有static修饰的变量. 区别: 静态变量是共享的,在整个JVM中只存在一个, 而成员变量是每一个实例所独有的.供实例自己使用. 例子: 一个学生类:年龄,姓名,性别是实例变量,因为每个人的年龄,姓名都可能不同: 而学费可以是类变量,每个学生的学费基本都是一样的.(特殊的除外) 应用场景: 当一个对象是这个类所有实例所共享的时候,用类变量 如果每个实例的值都可能不同,用实例变量. 静态变量根据声