2

I have a PHP app that uses 2 different databases. The connection is realized by a singleton mysql class. What I would like to achieve is to use the same class but to connect to another database depending on a variable stated when calling the class. So, the code used (but not yet functional):

/ start the single class
class Singleton {

// declare two private variables
private static $_instace;
private $conn;
var $dbc = 0;

// declare private constructor class
private function __construct() {
    $this->conn = mysql_connect(HOST, USER, PASS);
    //die('DB State: [' . $this->dbc . ']');
    if ($this->dbc) {
       mysql_select_db(DB_DATABASE_PS);
    } else {
       mysql_select_db(DBNAME);
    }
}

// create a singleton method
public static function getconnect($dbc = false) {
    if (!self::$_instace) {
        self::$_instace = new Singleton();   
        $_instace->dbc = $dbc;  
    } else {
        $_instace->dbc = $dbc;  
    }
    return self::$_instace;
}
}

When calling a class that uses the first database (DBNAME), it all works perfect but when trying to use the second database, the code doesn't help me at all.

The code to load the second database inside a new class is made trough this code:

public function __construct() {
   $this->connect = Singleton::getconnect(true);
}

Could someone help me figure it out? Thank you!

rosuandreimihai
  • 656
  • 3
  • 16
  • 39
  • There is a difference between `$instace` and `$instance` at a few locations... – arkascha Dec 27 '15 at 20:43
  • 1
    Looks like you use this class (or singleton) just as a factory. If so, then you don't have to instantiate an object at all, so there's no need to implement a singleton pattern, since you can simply turn it into a static class. – arkascha Dec 27 '15 at 20:44
  • Hi, modified the $instace variable, but the error still persists.. – rosuandreimihai Dec 27 '15 at 20:49
  • What error? You did not mention any "error" in the question. Or do you refer to the "the code doesn't help me at all"`If so, _what does that mean_? – arkascha Dec 27 '15 at 20:52
  • Sorry, for me the error is the fact that it doesn't work as needed.. – rosuandreimihai Dec 27 '15 at 20:52
  • _What does that mean_? – arkascha Dec 27 '15 at 20:53
  • 2
    The database is selected in the __construct method, which is called only once. When you make the second call, `Singleton::getconnect(true)` will set $dbc, but nothing will call `mysql_select` on the second database. – Richard St-Cyr Dec 27 '15 at 20:53
  • I am trying to get that class to change the database name when called with the argument ($dbc variable) set to true – rosuandreimihai Dec 27 '15 at 20:53
  • So, how should I use it (the singleton class) to change between the databases, keeping in mind that on a single page there could be data from both databases – rosuandreimihai Dec 27 '15 at 20:56

1 Answers1

2

The problem is, you're selecting the database during the construction of the object(in __construct() method) and it's completely based on the class member variable $dbc. So the next time you want to change the database, you have to call getconnect() method like this, Singleton::getconnect(true);, and then create another object to change the database, which would eventually defeat the purpose of singleton pattern. So basically, every time you change the database you have to call getconnect() method with true and false parameter alternatively, and create a new object to change the database.

Now comes down to your problem,

how should I use it (the singleton class) to change between the databases, keeping in mind that on a single page there could be data from both databases

Use the following code snippet to implement singleton pattern and change databases using a single object.

class Singleton {

    // declare two private variables
    private static $instance;
    private $conn;

    // Since it's constructor method is private
    // it prevents objects from being created from 
    // outside of the class
    private function __construct() {}

    // It creates an object if not previously created,
    // opens a connection to MySQL Server
    // and returns the object
    public static function getInstance() {
        if(!isset(self::$instance)){
            self::$instance = new Singleton();
            self::$instance->conn = mysql_connect(HOST, USER, PASS);
        }
        return self::$instance;
    }

    // set your database here
    public function setDatabase($db){
        return mysql_select_db($db, $this->conn);
    }

    // Execute your query here
    public function executeQuery($query){
        return mysql_query($query, $this->conn);
    }

    // Close your connection here
    public function closeConnection(){
        mysql_close($this->conn);
    }

}

// Get an instance of Singleton class
$obj = Singleton::getInstance();

// Set database "abc"
if($obj->setDatabase("abc")){
    echo "database has changed <br />";
}else{
    echo "database has not changed <br />";
}

// Display the selected database
$resultset = $obj->executeQuery("SELECT DATABASE() as db");
$row=mysql_fetch_assoc($resultset);
echo $row['db'] . "<br />";

// Set database "def"
if($obj->setDatabase("def")){
    echo "database has changed <br />";
}else{
    echo "database has not changed <br />";
}

// Display the selected database
$resultset = $obj->executeQuery("SELECT DATABASE() as db");
$row=mysql_fetch_assoc($resultset);
echo $row['db'] . "<br />";

// close connection
$obj->closeConnection();

Output:

database has changed
abc
database has changed
def

Sidenote: Please don't use mysql_ database extensions, they were deprecated in PHP 5.5.0 and were removed in PHP 7.0.0. Use mysqli or PDO extensions instead. And this is why you shouldn't use mysql_ functions.

Community
  • 1
  • 1
Rajdeep Paul
  • 16,887
  • 3
  • 18
  • 37
  • Hi, this sounds like it will actually work, but you have to keep in mind that I need to make as little modifications to the existing code, because there are a little over 200 php classes that runs the primary database, so I need the singleton class to choose by default one of the databases. – rosuandreimihai Dec 28 '15 at 15:02
  • Here is what I have in mind, altering a portion of your code, but it still doesn't work:`public static function getconnect($dbc = false) { if(!isset(self::$instance)){ self::$instance = new Singleton(); self::$instance->conn = mysql_connect(HOST, USER, PASS); self::$instance->setDatabase($dbc); } return self::$instance; }` – rosuandreimihai Dec 28 '15 at 15:03
  • `// set your database here public function setDatabase($dbc = false){ //die('DB State:' . $dbc); if ($dbc) { return mysql_select_db(DB_DATABASE_PS, $this->conn); } else { return mysql_select_db(DBNAME, $this->conn); } }` – rosuandreimihai Dec 28 '15 at 15:03
  • @rosuandreimihai Please elaborate *still doesn't work*. What's the error you're getting now? – Rajdeep Paul Dec 28 '15 at 15:42
  • Well, "still doesn't work" means that the requirements of my app would require a lot of changes using the code provided.. So, I would need a bit of code that would load by default one of the databases.. – rosuandreimihai Dec 28 '15 at 20:37