我从未见过像这样的代码:
public static function getInstance()
{
if ( ! isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
Run Code Online (Sandbox Code Playgroud)
它是一样的new className()吗?
编辑
如果该类是继承的,它指向哪个类?
Pas*_*TIN 202
self 指向它所写的类.
因此,如果您的getInstance方法位于类名中MyClass,则以下行:
self::$_instance = new self();
Run Code Online (Sandbox Code Playgroud)
将做同样的事情:
self::$_instance = new MyClass();
Run Code Online (Sandbox Code Playgroud)
编辑:评论后的几个更多信息.
如果您有两个相互扩展的类,则有两种情况:
getInstance 在子类中定义getInstance 在父类中定义第一种情况看起来像这样(我删除了所有非必要的代码,对于这个例子 - 你必须将它添加回来以获得单例行为)*:
class MyParentClass {
}
class MyChildClass extends MyParentClass {
public static function getInstance() {
return new self();
}
}
$a = MyChildClass::getInstance();
var_dump($a);
Run Code Online (Sandbox Code Playgroud)
在这里,你会得到:
object(MyChildClass)#1 (0) { }
Run Code Online (Sandbox Code Playgroud)
这意味着self手段MyChildClass- 即编写它的类.
对于第二种情况,代码看起来像这样:
class MyParentClass {
public static function getInstance() {
return new self();
}
}
class MyChildClass extends MyParentClass {
}
$a = MyChildClass::getInstance();
var_dump($a);
Run Code Online (Sandbox Code Playgroud)
你会得到这种输出:
object(MyParentClass)#1 (0) { }
Run Code Online (Sandbox Code Playgroud)
这意味着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);
Run Code Online (Sandbox Code Playgroud)
但是,static相反self,你现在会得到:
object(MyChildClass)#1 (0) { }
Run Code Online (Sandbox Code Playgroud)
这意味着static指向所使用的类(我们使用过的MyChildClass::getInstance()),而不是写入它的类.
当然,行为self没有改变,没有破坏现有的应用程序 - PHP 5.3只是添加了一个新的行为,回收static关键字.
并且,谈到PHP 5.3,您可能需要查看PHP手册的Late Static Bindings页面.
这似乎是Singleton模式的一个实现.该函数被静态调用并检查静态类是否具有变量$_instance集.
如果不是,则初始化self(new self())的实例并将其存储$_instance.
如果你打电话,className::getInstance()你将在每次调用时获得一个相同的类实例,这是单例模式的要点.
我从来没有见过这样做过,但老实说不知道这是可能的.什么$_instance声明在课堂上?
小智 7
这很可能用于单例设计模式,其中构造函数被定义为private,以避免被实例化,双冒号(::)运算符可以访问在类中声明为static的成员,因此如果有静态成员,则伪变量$这是不能使用的,因此代码使用self而不是,Singletons是良好的编程实践,只允许一个对象的实例,如数据库连接器处理程序.从客户端代码中,访问该实例将通过创建单个访问点来完成,在这种情况下,他将其命名为getInstance(),getInstance本身就是创建该对象的函数,基本上使用new关键字创建一个对象,这意味着构造函数方法是也被称为.
该行if(!isset(self::instance))检查是否已经创建了一个对象,你无法理解这一点,因为代码只是一个片段,在顶部的某个地方,应该有可能是静态成员
private static $_instance = NULL;
Run Code Online (Sandbox Code Playgroud)
在普通的课程中,我们可以简单地访问这个成员
$this->_instance = 'something';
Run Code Online (Sandbox Code Playgroud)
但它声明为静态,因此我们无法使用我们使用的$ this代码
self::$_instance
Run Code Online (Sandbox Code Playgroud)
通过检查是否存在一个存储在这个静态类变量上的对象,该类可以决定创建或不创建单个实例,所以如果没有设置,则为!isset,意味着静态成员$ _instance上不存在任何对象,则它生成一个新对象,$_instance通过该命令将其存储在静态成员中
self::$_instance = new self();
Run Code Online (Sandbox Code Playgroud)
并将其返回给客户端代码.然后客户端代码可以愉快地使用对象的单个实例及其公共方法,但是在客户端代码中,调用单个访问点,也就是说,该getInstance()方法也很棘手,必须像这样调用它
$thisObject = className::getInstance();
Run Code Online (Sandbox Code Playgroud)
原因是,函数本身被声明为静态.