3
class SingleTon
{
    private static $instance;

    private function __construct()
    {
    }

    public function getInstance() {
        if($instance === null) {
            $instance = new SingleTon();
        }
        return $instance;
    }
}

The above code depicts Singleton pattern from this article. http://www.hiteshagrawal.com/php/singleton-class-in-php-5

I did not understand one thing. I load this class in my project, but how would I ever create an object of Singleton initially. Will I call like this Singelton :: getInstance()

Can anyone show me an Singleton class where database connection is established?

Wesley Murch
  • 101,186
  • 37
  • 194
  • 228
theJava
  • 14,620
  • 45
  • 131
  • 172

5 Answers5

14

An example of how you would implement a Singleton pattern for a database class can be seen below:

class Database implements Singleton {
    private static $instance;
    private $pdo;

    private function __construct() {
        $this->pdo = new PDO(
            "mysql:host=localhost;dbname=database",
            "user",
            "password"
        );
    }

    public static function getInstance() {
        if(self::$instance === null) {
            self::$instance = new Database();
        }
        return self::$instance->pdo;
    }
}

You would make use of the class in the following manner:

$db = Database::getInstance();
// $db is now an instance of PDO
$db->prepare("SELECT ...");

// ...

$db = Database::getInstance();
// $db is the same instance as before

And for reference, the Singleton interface would look like:

interface Singleton {
    public static function getInstance();
}
  • What would be my parent singleton constructor look like parent::__construct("mysql:host=localhost;dbname=database", "user", "password"); – theJava Nov 01 '11 at 14:45
  • @theJava: In the example, I'm extending the class PDO, so PDO's [`__construct()`](http://php.net/manual/pdo.construct.php) would be that method. –  Nov 01 '11 at 14:46
  • @theJava: Since singletons must have a `getInstance()` method, the interface would define that you must declare it in your class. –  Nov 01 '11 at 14:50
  • @TimCooper $instance = new Database(); should be self::$instance = new Database(); – hafichuk Nov 01 '11 at 14:51
  • @hafichuk: Thanks. I missed that one. –  Nov 01 '11 at 14:52
  • In suggested code, the **Database::getInstance()** , getInstance should be **static**. Also in Java singleton patterns, the getInstance method is always static. Static methods are returning the methods of the class, public (nonstatic) methods are returning methods of the instance. – Mitja Gustin May 20 '13 at 11:33
  • All cute and cuddly, but a private/protected constructor does not work for me. I get this error trying to instantiate PDO this way: `Access level to Database::__construct() must be public (as in class PDO)` – Klemen Tusar May 19 '14 at 12:15
  • @techouse: I've updated my answer. It should hopefully work for you now. –  May 19 '14 at 12:20
  • @TimCooper works :) I would also suggest packing the PDO instantiation in a `try` ... `catch` block and throw an `Exception` in case there's something wrong :) – Klemen Tusar May 19 '14 at 13:09
  • @techouse: I'll just let the exception bubble up; let the caller of `Database::getInstance` deal with it. –  May 19 '14 at 13:10
1

Yes, you have to call using

SingleTon::getInstance();

The first time it will test the private var $instance which is null and so the script will run $instance = new SingleTon();.

For a database class it's the same thing. This is an extract of a class which I use in Zend Framework:

class Application_Model_Database
{
   /**
    *
    * @var Zend_Db_Adapter_Abstract
    */
   private static $Db = NULL;

   /**
    *
    * @return Zend_Db_Adapter_Abstract
    */
   public static function getDb()
   {
      if (self::$Db === NULL)
         self::$Db = Zend_Db_Table::getDefaultAdapter();
      return self::$Db;
   }
}

Note: The pattern is Singleton, not SingleTon.

Aurelio De Rosa
  • 21,856
  • 8
  • 48
  • 71
0
class Database{
    private static $link=NULL;
    private static $getInitial=NULL;

    public static function getInitial() {
         if (self::$getInitial == null)
         self::$getInitial = new Database();
         return self::$getInitial;
    }
    public function __construct($server = 'localhost', $username = 'root', $password ='tabsquare123', $database = 'cloud_storage') {

         self::$link = mysql_connect($server, $username, $password);
         mysql_select_db($database,self::$link);
         mysql_query("SET CHARACTER SET utf8", self::$link); 
         mysql_query("SET NAMES 'utf8'", self::$link); 
         return self::$link;
    }

    function __destruct(){
          mysql_close(self::$link);
    }
}
0

Since null coalescing operator was added in PHP 7.4. The simplest Singleton can looks like below:

class Singleton
{
    private function __construct()
    {
    }

    public static function getInstance(): self
    {
        static $instance;
        return $instance ??= new self();
    }
}

With PHP 8.0 when static return type was added, self can be replace with static to allow Singleton class be extendable without overriding getInstance() method

class Singleton
{
    private function __construct()
    {
    }

    public static function getInstance(): static
    {
        static $instance;
        return $instance ??= new static();
    }
}

$instance variable can be both local or class property. It depends you need access to it outside getInstance() method.

fela
  • 679
  • 8
  • 7
0

A few corrections to your code. You need to ensure that the getInstance method is 'static', meaning it's a class method not an instance method. You also need to reference the attribute through the 'self' keyword.

Though it's typically not done, you should also override the "__clone()" method, which short circuits cloning of instance.

<?
class Singleton
{
    private static $_instance;

    private function __construct() { }
    private final function __clone() { }

    public static function getInstance() {
        if(self::$_instance === null) {
            self::$_instance = new Singleton();
        }
        return self::$_instance;
    }
}
?>

$mySingleton = Singleton::getInstance();

One thing to not is that if you plan on doing unit testing, using the singleton pattern will cause you some difficulties. See http://sebastian-bergmann.de/archives/882-Testing-Code-That-Uses-Singletons.html

hafichuk
  • 10,351
  • 10
  • 38
  • 53