什么是新的自我(); 意味着在PHP?
我从来没有见过像这样的代码:
public static function getInstance() { if ( ! isset(self::$_instance)) { self::$_instance = new self(); } return self::$_instance; }
它和new className()
吗?
编辑
如果这个类是inheritance的,它指向哪个类?
self
指向它所写的类。
所以,如果你的getInstance方法在类名MyClass
,那么下面一行:
self::$_instance = new self();
会做同样的事情:
self::$_instance = new MyClass();
编辑:一些更多的信息,在评论之后。
如果你有两个相互延伸的类,你有两种情况:
-
getInstance
在子类中定义 -
getInstance
在父类中定义
第一种情况看起来像这样(我已经删除了所有非必要的代码,对于这个例子 – 你将不得不添加它来获得单例行为)*:
class MyParentClass { } class MyChildClass extends MyParentClass { public static function getInstance() { return new self(); } } $a = MyChildClass::getInstance(); var_dump($a);
在这里,你会得到:
object(MyChildClass)#1 (0) { }
这意味着self
意味着MyChildClass
– 即它所写的类。
对于第二种情况,代码将如下所示:
class MyParentClass { public static function getInstance() { return new self(); } } class MyChildClass extends MyParentClass { } $a = MyChildClass::getInstance(); var_dump($a);
你会得到这样的输出:
object(MyParentClass)#1 (0) { }
这意味着self
意味着MyParentClass
– 即这里也是它所写的类 。
当PHP <5.3时,“写入的类”是重要的,有时会导致问题。
这就是为什么PHP 5.3引入了static
关键字的一个新用法:现在可以在这些示例中正确使用self
:
class MyParentClass { public static function getInstance() { return new static(); } } class MyChildClass extends MyParentClass { } $a = MyChildClass::getInstance(); var_dump($a);
但是,与static
而不是self
,你现在将得到:
object(MyChildClass)#1 (0) { }
这意味着static
类指向所使用的类 (我们使用MyChildClass::getInstance()
),而不是写入的类。
当然, self
的行为并没有改变,为了不破坏现有的应用程序–PHP 5.3只是增加了一个新的行为,回收static
关键字。
而且,在谈到PHP 5.3时,您可能需要查看PHP手册的Late Static Bindings页面。
这似乎是Singleton模式的实现。 该函数被静态调用,并检查静态类是否具有variables$_instance
set。
如果不是,则它初始化自己的一个实例( new self()
)并将其存储在$_instance
。
如果调用className::getInstance()
,每次调用都会得到一个相同的类实例,这是singleton模式的要点。
尽pipe如此,我从来没有见过这样做,但实际上并不知道这是可能的。 在类中声明的$_instance
是什么?
这很可能用于单例devise模式,其中构造函数被定义为私有的,以避免被实例化,双冒号(::)
运算符可以访问在类内声明为静态的成员,所以如果存在静态成员,伪variables$ this不能被使用,因此代码使用self而不是Singletons是很好的编程实践,它将只允许一个对象的实例,如数据库连接器处理程序。 从客户端代码中,通过创build一个访问点来访问该实例,在这种情况下,他将其命名为getInstance()
。getInstance本身就是创build该对象的函数,基本上使用new关键字创build一个对象,意思是也称为构造函数方法。
if(!isset(self::instance))
检查一个对象是否已经被创build,你不能理解这个,因为代码只是一个片段,在顶部的某个地方,
private static $_instance = NULL;
在正常的课程中,我们可以简单地访问这个成员
$this->_instance = 'something';
但它声明的静态,所以我们不能使用我们使用的$代码
self::$_instance
通过检查这个静态类variables是否存在一个对象,这个类可以决定是否创build一个单独的实例,所以如果没有设置!isset,意味着静态成员$ _instance中没有对象存在,那么它会生成一个新的对象,并通过命令将其存储在静态成员$_instance
self::$_instance = new self();
并将其返回给客户端代码。 然后客户端代码可以愉快地使用对象的单个实例和其公共方法,但是在客户端代码中,调用单个访问点,也就是getInstance()
方法也很棘手,必须像这样调用
$thisObject = className::getInstance();
原因,这个函数本身被声明为静态的。
是的,它就像new className()
(指包含该方法的类),可能在构造函数是私有的单例模式中使用。
如果这个类是inheritance的,那么从孩子调用getInstance()将不会给你一个孩子的实例。 它只会返回父实例的一个实例。 这是因为我们称之为新自我()。
如果您希望子类将返回子类的实例,则在getInstance()中使用新的static(),然后它将返回子类实例。 这被称为晚绑定!