PHP静态类为何保留调用数据?单例模式执行结果存疑
我写了一段PHP代码,本以为每次调用静态方法get()时,类会被重新加载,静态属性$User会是空的,从而每次都创建新对象,但实际结果和预期不符,想请教下原因:
我的代码:
class User { private static $User; public static function get() { if (empty(self::$User)) { echo "Create New Object<br/>"; return self::$User = new User(); } echo "Already Created<br/>"; return self::$User; } } User::get(); User::get(); User::get(); User::get();
实际运行输出
Create New Object
Already Created
Already Created
Already Created
我预期的输出
Create New Object
Create New Object
Create New Object
Create New Object
我原本以为调用静态方法时会重新加载类,每次调用时$User都为空,所以会创建新对象,为何代码会保留之前的类数据?
这其实是对PHP中静态属性和类加载机制的误解啦:
类只会被加载一次:PHP在第一次使用类(比如第一次调用静态方法
User::get())时,就会把整个类的定义加载到内存中,后续再调用类的方法或者实例化,都不会重新加载类,类的状态会一直保存在内存里直到脚本执行结束。静态属性属于类本身:
private static $User是类级别的属性,它不属于任何一个User实例,而是属于User这个类。一旦你第一次调用get()时给它赋值了新的User对象,这个值就会一直存在于类的静态属性中,除非你主动去重置它(比如self::$User = null;)。所以后续再调用get()时,empty(self::$User)会返回false,自然不会创建新对象。
如果你的需求就是每次调用get()都生成新对象,那完全不需要静态属性来保存实例,直接在方法里返回新对象就行,修改后的代码如下:
class User { public static function get() { echo "Create New Object<br/>"; return new User(); } } User::get(); User::get(); User::get(); User::get();
这样运行后就会和你的预期输出一致啦。
内容的提问来源于stack exchange,提问作者Hamza

