tags:

views:

58

answers:

3

I use a static function to create a PDO object.

It accepts 2 params: a string and an object which contains the connection settings (dns, user, pass).

in order to prevent unnecessarily creating duplicate PDO connections with the same name, I tried to create a multi-key dictionary to cache the PDO object in.

Here is what I did:

include_once('IPDOSettings.php');

class PDOManager
{
    private static $connections; // array of connections

    public static function getConnection(IPDOSettings $settings, $connection_name = 'default')
    {
        $dictionary_key = array('name' => $connection_name, 'settings' => $settings);
        if(!self::$connections[$dictionary_key])
        {
            $DBH = new PDO($settings->getDNS(),$settings->getUser(),$settings->getPass());
            self::$connections[$dictionary_key] = $DBH;
        }
        return self::$connections[$dictionary_key];
    }

}

However after testing this I get this error Illegal offset type. After looking it up I find out that you cannot use objects or arrays as keys.

So is there anyway to do what I am trying to achieve?

+2  A: 

Have a look at SplObjectStorage, it allows you to use an object as key.

nikic
+2  A: 

I would do something like this:

$dictionary_key = $connection_name . $settings->toString();
livingtech
obviously, you need to write a toString function on your `IPDOSettings` object.
livingtech
+2  A: 

Not really an answer to your question but do you expect PDOManager::getConnection() being called multiple times with the same $connection_name but different settings? Do you need to store the settings along with the db handle in your cache?

This problem wouldn´t even occur if you´d just store the connections by name:

    // my suggestion/idea: use $connection_name as key
    $dictionary_key = $connection_name; 

    if(!self::$connections[$dictionary_key])
    {
        $DBH = new PDO($settings->getDNS(),$settings->getUser(),$settings->getPass());
        self::$connections[$dictionary_key] = $DBH;
    }
    return self::$connections[$dictionary_key];

EDIT:

Well, if you cant just use $connection_name as a key, you could combine $connection_name and use spl_object_hash() in order to get your key:

    $dictionary_key = $connection_name . spl_object_hash($settings); 

This is much nicer then e. g. using serialize() to get a string representation of the $settings object.

Max
Actually yes, I often have to connect to multiple data bases. So "default" connection to DB1 would override "default" connection to DB2.
John Isaacks
What you recommended was what I was going to do originally until I tried to make it support multiple connections to multiple DBs.
John Isaacks
@John Isaacks it was an idea, sometimes easy stuff is the best. Maybe my edit gives you another approach?
Max
Thanks, that make sense!
John Isaacks
Actually if I understand correctly, using separate settings objects with the same settings (not that that should ever happen!) would return the same string if serialized but different string with spl_object_hash.
John Isaacks
By the way, I think I might just go back to the drawing board all together here, because I think I am over complicating things, and I would prefer not having to pass the settings around every time if I can figure out a solution not to.
John Isaacks