Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error in Implementing singleton pattern

I am trying to implement singleton pattern and i am getting the following error

Fatal error: Access level to Database::__construct() must be public (as in class PDO) in /config/database.php on line 29

<?php

class Database extends PDO
{
    private static $instance;

    private function __construct()
    {

            return parent::__construct(
                    "mysql:host=localhost;dbname=live",
                    "root",
                    "root"
            );

    }

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

    public function __clone() 
    {
        die(__CLASS__ . ' class cant be instantiated. Please use the method called getInstance.');
    }
}


$mySingleton = Database::getInstance();

var_dump($mySingleton);

?>
like image 522
aWebDeveloper Avatar asked Dec 27 '22 04:12

aWebDeveloper


2 Answers

By declaring the __construct() function as private like private function __construct() you are effectively disallowing PHP from automatically calling it upon object creation.

Instead, you should always have your __construct() as well as other magic methods declared public.

public function __construct() 
{
   // Now PHP can access me
}

As far as making your Database class follow a singleton pattern, it doesn't make sense to extend a class that doesn't (i.e. PDO). Instead, do something like this:

<?php

class Database
{
    private static $instance;

    public function __construct()
    { 
        // Check to see if static PDO instance
        // has already been created, so we create only one (singleton)
        if(!self::$instance)
        {
            self::$instance = new PDO(
                "mysql:host=localhost;dbname=live",
                "root",
                "root"
            );
         }
    }

    public function getInstance() {
        if(self::$instance === null) {
            self::__construct();
        }
        return self::$instance;
    }

    public function __clone() 
    {
        die(__CLASS__ . ' class cant be instantiated. Please use the method called getInstance.');
    }
}


$mySingleton = Database::getInstance();

var_dump($mySingleton);

?>
like image 192
Jeremy Harris Avatar answered Jan 08 '23 23:01

Jeremy Harris


You can't change the Access level for a override method.

Instead of extending PDO, you could just have a PDO instance in Database. Composition is more flexible than inheritance.

like image 24
xdazz Avatar answered Jan 08 '23 22:01

xdazz