什么是新的自我(); 意味着在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(),然后它将返回子类实例。 这被称为晚绑定!