2

Let's say I'm writing a PHP (>= 5.0) class that's meant to be a singleton. All of the docs I've read say to make the class constructor private so the class can't be directly instantiated.

So if I have something like this:

class SillyDB
{
  private function __construct()
  {

  }

  public static function getConnection()
  {

  }
}

Are there any cases where __construct() is called other than if I'm doing a

new SillyDB() 

call inside the class itself?

And why am I allowed to instantiate SillyDB from inside itself at all?

  • 2
    I think you'll find useful [this answer](http://stackoverflow.com/a/4596323/2637490) – Alma Do Oct 22 '13 at 13:37
  • [Obligatory singletons are evil link](http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons). – Mike Oct 22 '13 at 13:38

5 Answers5

3

A private constructor makes sure you cannot instanciate this class outside of itself.
So calling

$obj = new SillyDB();

would result in an error.

This technique is usually used when creating singleton classes.

This stone old comment in the manual describes it pretty well: http://www.php.net/manual/de/language.oop5.decon.php#80314

You have a static method inside the class that manages a single instance of the class which can be retreived through the method.

Cobra_Fast
  • 15,671
  • 8
  • 57
  • 102
2

Calling the static function within that class may run the construct from within the class.

class SillyDB
{
  private function __construct()
  {
    $db->connect();
  }

  public static function getConnection()
  {
    self::__construct();
  }
}

Running

SillyDB::getConnection()

will run the __construct() method and connect you to the db

Nolan Knill
  • 499
  • 5
  • 19
1

Are there any cases where __construct() is called other than if I'm doing a new SillyDB() call inside the class itself?

No.

And why am I allowed to instantiate SillyDB from inside itself at all?

Why would you not be allowed to?

The better question would be what use is it for a constructor that can only be called from inside its own class?. That is useful when you want to ensure total control of how instances are created, for example when you implement a singleton.

Jon
  • 428,835
  • 81
  • 738
  • 806
0

__construct() would only be called if you called it from within a static method for the class containing the private constructor. So for your Singleton, you might have a method like so:

class DBConnection
{
   private static $Connection = null;

   public static function getConnection()
   {
      if(!isset(DBConnection::$Connection))
      {
         DBConnection::$Connection = new DBConnection();
      }
      return DBConnection::$Connection;
   }

   private function __construct()
   {

   }
}

$dbConnection = DBConnection::getConnection();

The reason you are able/would want to instantiate the class from within itself is so that you can check to make sure that only one instance exists at any given time. This is the whole point of a Singleton, after all. Using a Singleton for a database connection ensures that your application is not making a ton of DB connections at a time.

SteeveDroz
  • 6,006
  • 6
  • 33
  • 65
Legionar
  • 7,472
  • 2
  • 41
  • 70
0

You are able to call it because scope is checked based on class rather than instance (i.e. an object is able to access the private and protected methods/properties of another instance of the same class without issue)

Danny
  • 709
  • 8
  • 13