views:

84

answers:

2

I'm building a PHP application which has to interact with several structurally identical databases. I'd like to use a singleton factory to hand out connections to the databases and minimize the number of duplicate connections. I'd also like to wrap the database class with a few functions.

It would be extremely convenient if I could do all this in a single class. I tried using a singleton factory (it seemed like a good idea at the time), only to realize that it seems like has to return other classes to be useful. Is there an easy way to combine the singleton factory and database wrapping functionality, or should I just put the database wrapping functions in another class?

static private $instance = array();

private function __construct($name) {
    switch ($name) {
        //select db connection
    }

    $this->db = $this->getDb();
    return;
}

protected function __clone() {

}

public static function singleton($name) {
    if (!isset(self::$instance[$name])) {
        $c = __CLASS__;
        self::$instance[$name] = new $c($name);
    }
    return self::$instance[$name];
}

public function wrapperFunction() {
    //stuff
}
+1  A: 

I do something similar quite often (Managing multiple database connections by name for example). The one change I'll suggest is making the constructor and $instance array protected. The reason is that it becomes FAR easier to test that way (since you can extend it with a wrapper class to be able to access them and create and destroy instances as you need to). Sure, that opens up the possibility for someone to do that in the application, but why throw away the possibility of managing instances from a child class?

Just my $0.02...

ircmaxell
A: 

It looks like this would probably be possible by using some class-wide state variables and doing some clever things with func_num_args and func_get_arg in the constructor.

However, in the interest of reducing the number of WTFs per minute, I'll go with GoalBased's suggestion of splitting things up into two classes.

James