New self()在 PHP 中是什么意思?

我从未见过这样的代码:

public static function getInstance()
{
if ( ! isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}

new className()一样吗?

剪辑

If the class is inheritant,which class does it point to?

98089 次浏览

self指向编写它的类。

因此,如果 getInstance 方法位于类名 MyClass中,那么下面一行:

self::$_instance = new self();

将做同样的事情:

self::$_instance = new MyClass();


编辑: 更多信息,在评论之后。

如果有两个相互扩展的类,那么有两种情况:

  • getInstance is defined in the child class
  • 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);

And you'd get this kind of output :

object(MyParentClass)#1 (0) { }

这意味着 self意味着 MyParentClass——也就是说,这里也是 写它的类




使用 PHP 这就是为什么 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) { }

Which means that static sort of points to 使用的类 (we used MyChildClass::getInstance()), and not the one in which it is written.

当然,为了不破坏现有的应用程序,self的行为没有改变—— PHP 5.3刚刚添加了一个新的行为,回收了 static关键字。


说到 PHP 5.3,您可能需要查看 PHP 手册的[后期静态绑定][1]页面。

是的,它类似于 new className()(指包含该方法的类) ,可能用在构造函数是私有的单例模式中。

This seems to be an implementation of the 单例模式. 该函数被静态调用,并检查静态类是否具有变量 $_instance集。

如果不是,它将初始化自己的实例(new self())并将其存储在 $_instance中。

如果你调用 className::getInstance(),每次调用都会得到 一模一样类实例,这就是单例模式。

我从没见过这样的方式,说实话,我也不知道这是可能的。 类中声明的 $_instance是什么?

这最有可能用于单例设计模式,其中构造函数被定义为私有的,以避免被实例化,双冒号 (::)操作符可以访问类中声明为静态的成员,所以如果有静态成员,伪变量 $This 不能使用,因此代码使用 self 代替,单例是良好的编程实践,只允许一个对象的实例,如数据库连接器处理程序。从客户端代码来看,访问该实例将通过创建一个单一的访问点来完成,在这个例子中,他将其命名为 getInstance(),getInstance 本身就是创建对象的函数,基本上使用 new 关键字来创建一个对象,这意味着构造函数方法也被调用。

if(!isset(self::instance))行检查一个对象是否已经被创建,你不能理解这一点,因为代码只是一个片段,在顶部的某个地方,应该有静态成员,比如可能

private static $_instance = NULL;

在普通类中,我们可以通过简单的方法访问这个成员

$this->_instance = 'something';

but its declared static and so we could not use the $this code we use instead

self::$_instance

通过检查这个静态类变量上是否存在对象,类可以决定创建或不创建单个实例,所以如果它没有被设置,!Isset,意味着静态成员 $_ instance 上不存在对象,然后它生成一个新对象,通过命令将其存储在静态成员 $_instance

self::$_instance = new self();

然后返回到客户端代码。然后客户端代码可以愉快地使用对象的单个实例和它的公共方法,但是在客户端代码中,调用单个访问点,也就是说,getInstance()方法也很棘手,必须这样调用

$thisObject = className::getInstance();

原因是,函数本身被声明为静态的。

如果类是继承的,那么从 child 调用 getInstance ()将不会给出 child 的实例。它只返回父实例的实例。 这是因为我们称之为 new self ()。

If you want that the child class will return an instance of child class then use new static() in the getInstance() and it will then return the child class instance. This is called late binding!!