I've never seen 开发者_运维问答code like this:
public static function getInstance()
{
if ( ! isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
Is it the same as new className()
?
EDIT
If the class is inheritant,which class does it point to?
self
points to the class in which it is written.
So, if your getInstance method is in a class name MyClass
, the following line :
self::$_instance = new self();
Will do the same as :
self::$_instance = new MyClass();
Edit : a bit more information, after the comments.
If you have two classes that extend each other, you have two situations :
getInstance
is defined in the child classgetInstance
is defined in the parent class
The first situation would look like this (I've removed all non-necessary code, for this example -- you'll have to add it back to get the singleton behavior)* :
class MyParentClass {
}
class MyChildClass extends MyParentClass {
public static function getInstance() {
return new self();
}
}
$a = MyChildClass::getInstance();
var_dump($a);
Here, you'll get :
object(MyChildClass)#1 (0) { }
Which means self
means MyChildClass
-- i.e. the class in which it is written.
For the second situation, the code would look like this :
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) { }
Which means self
means MyParentClass
-- i.e. here too, the class in which it is written.
With PHP That's why PHP 5.3 introduces a new usage for the
static
keyword : it can now be used exactly where we used self
in those examples :
class MyParentClass {
public static function getInstance() {
return new static();
}
}
class MyChildClass extends MyParentClass {
}
$a = MyChildClass::getInstance();
var_dump($a);
But, with static
instead of self
, you'll now get :
object(MyChildClass)#1 (0) { }
Which means that static
sort of points to the class that is used (we used MyChildClass::getInstance()
), and not the one in which it is written.
Of course, the behavior of self
has not been changed, to not break existing applications -- PHP 5.3 just added a new behavior, recycling the static
keyword.
And, speaking about PHP 5.3, you might want to take a look at the [Late Static Bindings][1] page of the PHP manual.
This seems to be an implementation of the Singleton pattern.
The function is called statically and checks whether the static class has the variable $_instance
set.
If it isn't, it initializes an instance of itself (new self()
) and stores it in $_instance
.
If you call className::getInstance()
you will get one and the same class instance on every call, which is the point of the singleton pattern.
I've never seen it this done this way, though, and honestly didn't know it was possible.
What is $_instance
declared as in the class?
This is most likely used in singleton design pattern, wherein the constructor is defined as private so as to avoid being instantiated, the double colon (::)
operator can access members that are declared static inside the class, so if there are static members, the pseudo variable $this cannot be used, hence the code used self instead, Singletons are good programming practices that will only allow 1 instance of an object like database connector handlers. From client code, accessing that instance would be done by creating a single access point, in this case he named it getInstance()
, The getInstance in itself was the function that created the the object basically using the new keyword to create an object meaning the constructor method was also called.
the line if(!isset(self::instance))
checks if an object has already been created, you could not understand this becuase the code is just a fragment, somewhere in the top, there should be static members like probably
private static $_instance = NULL;
in normal classes we would have accessed this member by simply
$this->_instance = 'something';
but its declared static and so we could not use the $this code we use instead
self::$_instance
by checking if there is an object stored on this static class variable, the class can then decide to create or not to create a single instance, so if its not set, !isset, meaning no object exists on the static member $_instance, then it generates a new object, stored it in the static member $_instance
by the command
self::$_instance = new self();
and returned it to client code. The client code can then happily use the single instance of the object with its public methods, but in the client code, calling the single access point, that is, the getInstance()
method is also tricky, it has to be called like this
$thisObject = className::getInstance();
the reason, the function in itself is declared static.
Yes, it's like new className()
(referring to the class containing that method), probably used in a Singleton pattern where the constructor is private.
If the class is inherited then calling getInstance() from child will not give you a instance of child. It will only returns an instance of parent instance. This is because we call 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!!
精彩评论