What does new self(); mean in PHP?

PhpClassSelf

Php Problem Overview


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?

Php Solutions


Solution 1 - Php

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 < 5.3, that "the class in which it is written" is important -- and can sometimes cause problems.

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 page of the PHP manual.

Solution 2 - Php

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?

Solution 3 - Php

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.

Solution 4 - Php

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

Solution 5 - Php

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser198729View Question on Stackoverflow
Solution 1 - PhpPascal MARTINView Answer on Stackoverflow
Solution 2 - PhpPekkaView Answer on Stackoverflow
Solution 3 - PhpflimhView Answer on Stackoverflow
Solution 4 - PhpMatteo RivaView Answer on Stackoverflow
Solution 5 - PhpktaView Answer on Stackoverflow