What does new self(); mean in PHP?
Asked Answered
T

5

128

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?

Towner answered 7/3, 2010 at 13:36 Comment(5)
https://mcmap.net/q/44954/-when-should-i-use-39-self-39-over-39-this-39Alleged
@stereofrog,do you mean singleton pattern should be abandoned?But all things exist for a reason,right?Towner
Oh,I tend to agree with this point:singleton should be replaced by factoryTowner
@stereofrog Singleton's are poison to unit-testing, it's extremely difficult to make immutable tests on something that changes state from one call to the next.Surfacetosurface
Unfortunately, this method will not extend. It will always give you a new object from the class in which this function was defined.Linage
A
245

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 class
  • getInstance 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.
Amberjack answered 7/3, 2010 at 13:41 Comment(3)
@Paul : heu... meant "self acts as an alias to", or "self sort of points to" -- the "designer" verb, in french, can be used for that -- I suppose that's one of the situations in which using the same word in english is not a good idea ;-( I'll edit my answer to fix this ;; thanks :-)Amberjack
What if there is baseclass,class,which one does it point to?Towner
@user : I've edited my answer to give a bit more informations about self and inheritance ; and I've also included some informations about static in PHP 5.3 ;; hope this helps :-)Amberjack
R
10

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?

Runge answered 7/3, 2010 at 13:41 Comment(1)
$_instance is declared as public static $_instance;Eugenides
R
7

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.

Reddy answered 25/11, 2010 at 5:25 Comment(0)
A
3

Yes, it's like new className() (referring to the class containing that method), probably used in a Singleton pattern where the constructor is private.

Angloirish answered 7/3, 2010 at 13:41 Comment(2)
Why would someone use the Singleton pattern in PHP? Unless used in a daemon-like program, the singleton will only live while the script runs and then disappear along with the program.Evanish
to avoid irritatingly declaring global to access a global variableSpectroheliograph
P
0

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!!

Ptero answered 27/9, 2015 at 7:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.