【问题标题】:PHP: How Do I Get a MySQL Link Identifier For an Already Open Connection?PHP:如何为已经打开的连接获取 MySQL 链接标识符?
【发布时间】:2009-08-26 07:52:35
【问题描述】:

当您使用 mysql_connect() 打开 MySQL 连接时,它会返回一个链接标识符。但是,如果您想稍后在脚本中再次获取该链接标识符怎么办? (例如:一个插件,需要打开一个新的数据库连接,仍然访问旧的。)

我正在寻找一种将链接标识符返回到 mysql_connect() 打开的最后一个连接的方法。有这样的功能吗?

【问题讨论】:

    标签: php mysql


    【解决方案1】:

    即使 Anti Veeranna 的解释是正确的,也有 一种非常直接的方式来做你想做的事。如果您阅读mysql_connect() 的文档,您会发现该函数有第四个参数“new_link”,默认为 false。如果您使用相同的参数再次调用 mysql_connect()(可能就是这种情况),它不会创建新连接,而是会返回旧连接的资源标识符。

    任何时候;)

    【讨论】:

    • 否决链接到 LMGTFY。我通过谷歌得到了这个答案。一个完整的超链接不会受到伤害。
    • @Mark,您通过 Google 找到了此答案。为什么 LMGTFY 会影响您的搜索?超链接没有损坏。
    • @XedinUnknown 出于所有意图和目的,确实如此。在搜索获取链接标识符的方法时,我在 Google 上找到了这个答案,然后愚蠢地点击了您的链接,以为它会带我到 php.net。相反,我得到了一个聪明的答案,让我等了 30 秒,这样你就可以嘲讽 OP。
    • 另一方面,我确实花了几分钟时间在这里检查和记录这个方法。如果您如此担心自己的 30 秒,为什么不完全按照 LMGTFY 链接演示的方式进行操作?毕竟,这就是 LMGTFY 的全部意义所在。
    【解决方案2】:

    不,没有。您必须自己记录链接标识符。您可以将链接标识符定义为类属性,这样您就可以轻松地从您的方法中访问它,而不必担心一遍又一遍地将其作为变量传递。

    【讨论】:

      【解决方案3】:

      感谢大家的回复。

      我最终打开了自己的连接,当我的插件完成后,最后一行重新打开了初始连接,因此主脚本的其余部分可以使用它期望的数据库。我知道这很草率,但在这种情况下似乎没有更好的选择。 :/

      更新:: 我已在 php.net 上将此作为功能请求提交。链接为:http://bugs.php.net/bug.php?id=49400

      【讨论】:

        【解决方案4】:

        您必须将句柄存储在 var 中。

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

        您可以在脚本中重复使用 $link,在新的 HTTP 请求之前。

        【讨论】:

          【解决方案5】:

          您要么必须自己存储链接标识符,如其他答案中所述,要么您可以简单地省略它,mysql_* 函数可以重用现有句柄

          mysql_query 帮助解释如下:

          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.
          

          我自己不会使用这种重用行为,除非您完全确定您的应用程序(或任何插件等)没有打开与其他数据库的任何新连接。

          【讨论】:

            【解决方案6】:

            使用mysql_pconnect,它会做你想做的事。

            首先,在连接时,该函数将首先尝试查找已使用相同主机、用户名和密码打开的(永久)链接。如果找到,将返回它的标识符,而不是打开新连接。

            您还可以使用静态或单例类来为您处理连接池。

            <?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");
            ?>
            

            【讨论】:

            • 我不认为这实际上是他们想要的 - 我认为他们想要打开一个到不同服务器的数据库连接,但 覆盖任何现有的“当前最后一个打开的数据库资源”,包含其插件的脚本可能一直依赖它。
            • 据我了解,最初的问题是“如何在不明确记录连接标识符的情况下重用以前打开的数据库连接”。如果我错了,那我就是,但我就是这么看的。
            • 啊,我现在明白你是对的。但是,mysql_pconnect 仍然会执行请求,因为它根据主机、用户名和密码识别连接。如果您需要将数据库包含在“唯一性”中,最好按照我的建议使用自定义类进行连接池。我真的不明白为什么我投了反对票。
            • 它不会执行请求 - 这里的场景是其他人的脚本正在执行 mysql_connect(或 pconnect)并且 保存资源链接,而是信任“最近打开的资源”是他们打开的资源。如果 OP 的插件将 pconnect 用于不同的主机,“最近打开的资源”将更改为新的资源 ID,即使旧资源仍然存在 - 但依赖“最近”资源的原始脚本是它自己的将被打破,因为不再是这种情况。
            • 在这种情况下,这只是一个设计缺陷(恕我直言)。如果您的架构允许插件但不提供访问数据库的机制,您应该重新设计。但我想你是对的,我的解决方案并不是人们所追求的。
            猜你喜欢
            • 1970-01-01
            • 2011-12-07
            • 2012-08-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-05-11
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多