tags:

views:

498

answers:

5

When you open a MySQL connection with mysql_connect(), it returns a link identifier. But what if you want to get that link identifier again later in the script? (for example: A plug-in, that needs to open a new database connection, and still access the old one.)

I'm looking for a way to return a link identifier to the last connection opened by mysql_connect(). Is there a function that does this?

+1  A: 

No, there isn't. You have to record link identifiers yourself. You could define link identifier as a class property, so that you can easily access it from your methods and don't have to worry about passing it as a variable over and over again.

RaYell
A: 

Use mysql_pconnect, that will do what you want.

First, when connecting, the function would first try to find a (persistent) link that's already open with the same host, username and password. If one is found, an identifier for it will be returned instead of opening a new connection.

You could also use a static or singleton class to handle connection pooling for you.

<?php
class dbConnectionPooler
{
    static var $connections = array();

    private static function createConnection($host, $username, $password, $db) {
        $connection = mysql_pconnect($host, $username, $password);

        if (FALSE !== $connection) {
            $result = mysql_select_db($db, $connection);

            if (FALSE !== $result) {
                self::$connections[self::getConnectionHash($host, $username, $password, $db)] = $connection;

                return $connection;
            }
        }
    }    

    private static function getConnectionHash($host, $username, $password, $db) {
        return md5($host. $username. $password. $db); // use your favourite hashing function here
    }

    public static function getConnection($host, $username, $password, $db) {
        $connectionHash = self::getConnectionHash($host, $username, $password, $db);

        if (array_key_exists($connectionHash, self::$connections)) {
            return self::$connections[$connectionHash];
        } else {
            return self::createConnection($host, $username, $password, $db);
        }

        return false;
    }
}

$connection = dbConnectionPooler::getConnection("dbhost", "dbuser", "dbpassword", "mydb");
?>
nikc
I don't think that's actually what they want - I think they're wanting to open a db connection to a different server, but *not* overwrite any existing "current last opened db resource" that a script which includes their plugin might have been relying on.
Amber
As I understand it, the original question was "How can I reuse a previously opened DB connection, without explicitly recording the connection identifier". If I'm wrong, then I am, but that's how I see it.
nikc
Ah, I see now that you're correct. However, mysql_pconnect will still do what is requested, since it identifies connections according to host, username and password. If you need to include the database into the "uniqueness", you're better off using a custom class for connection pooling, as I suggested. I can't really see why I got a downvote.
nikc
Added an example.
nikc
It won't do what is requested - the scenario here is that someone else's script is doing mysql_connect (or pconnect) and *not* saving the resource link, but instead trusting that the 'most recently opened resource' is the one that they opened. If the OP's plugin uses pconnect for a different host, the 'most recently opened resource' will change to the new resource id, even though the old resource will still be around - but the original script that's relying on the 'most recent' resource being its own will be broken since that's no longer the case.
Amber
In that case, it's simply a design flaw (IMHO). If you have an architecture that allows plugins but doesn't provide a mechanism for accessing the database, you should redesign. But I suppose you're right and my solution is not what was sought after.
nikc
A: 

You have to store your handle in a var.

$link = mysql_connect($host, $login, $pass);

And you can reuse $link along your script, before a new HTTP request.

mere-teresa
A: 

You either have to store the link identifier yourself as mentioned in other answers OR you can simply omit it, the mysql_* functions can reuse the existing handle

mysql_query help explains it like this:

resource mysql_query  ( string $query  [, resource $link_identifier  ] )

link_identifier

    The MySQL connection. If the link identifier is not specified, the last link opened by mysql_connect() is assumed.

I would not use that reuse behaviour myself though, unless you are completely sure that your application (or any plugins, etc) are not opening any new connections to other databases.

Anti Veeranna
A: 

Thanks to everyone for the replies.

I ended up opening my own connection, and when my plug-in was done, the last line reopens the initial connection so the rest of the main script can use the database it expects. It's sloppy, I know, but it doesn't seem like there's a better option in this case. :/

Update:: I've submitted this as a feature request on php.net. The link is: http://bugs.php.net/bug.php?id=49400

Nick