PHP,可变范围问题

时间:2011-04-24 07:06:41

标签: php mysql scope

我的问题是我在我的常规脚本代码和我的一个函数中使用变量$ db。它的目的是成为用于MySQL连接的变量。我需要在函数内部将一些数据写入数据库。在我的脚本中,我不能假设现有的数据库连接将打开,所以我打开一个新的连接并在函数退出之前将其关闭。自从这样做以后,我在脚本运行后收到错误,说MySQL引用不好/不存在。

我唯一可以解决的是在我的核心代码中,我使用变量$ db作为数据库连接的变量名。我也在函数中使用相同的变量。我没想到这会是一个问题,因为我没有在函数中使用$ db前面的全局。这应该意味着我的函数中的$ db I引用位于函数private scope中,但它似乎关闭了公共$ db的连接。

有什么想法吗?

我的代码片段是:

database.php中

db_connect()
{
 // open mysql db connection and return it;
}

db_close( &$db )
{
 // close the passed by reference db connection
}

api.php

api_verify( $keyid, $userid, $key )
{
  // open a new db connection
  $db = db_connect();

  // check for errors. if any errors are found note them in the db

  // close the db
  db_close($db);
}

main.php

include api.php;
include database.php;

// open a connection to the db
$db = db_connect();

// pull a list of things to process from the db and move through them one at a time
  // call api_verify() on each key before working through it's data.

db_close($db)

3 个答案:

答案 0 :(得分:2)

要管理数据库连接,您可以创建一个类而不是一对函数。如果您说“MySQL引用”,确切的错误是指“MySQL资源”,那么您使用的是过时的mysql扩展,应该切换到更现代的扩展,例如PDO。

class DBConnection {
    protected static $_connections = array(),
    static connect($dsn) {
        if (!isset(self::$_connections[$dsn])) {
            $credentials = self::getCredentials();
            /* Create connection. For example: */
            try {
                self::$_connections[$dsn][0] = new PDO($dsn, $credentials['username'], $credentials['password']);
            } catch (PDOException $exc) {
                // erase the frame w/ password from call trace to prevent leak.
                throw new PDOException($exc->getMessage(), $exc->getCode());
            }
            /* End create connection example */
            self::$_connections[$dsn][0]->dsn = $dsn;
        }
        ++self::$_connections[$dsn]['count'];
        return self::$_connections[$dsn][0];
    }
    static close($db) {
        if (isset(self::$_connections[$db->dsn])) {
            if (--(self::$_connections[$db->dsn]['count']) < 1) {
                unset(self::$_connections[$db->dsn]);
            }
        }
    }
    static getCredentials() {
        /* credentials can be stored in configuration file or script, in this method, or some other approach of your own devising */
    }
}

请注意,这不完全是OOP(它是,但仅限于技术意义上)。以上内容不适合单元测试。如果您想要更多OO方法(更适合单元测试),请扩展或包装PDO。使用dependency injection也可以解决上述coupling问题。

答案 1 :(得分:1)

我会假设发生的事情是连接取消,因为已经有连接,然后关闭结束当前连接。
我建议A)在文件的开头开始连接,只知道它总是在那里(我做的);或者B)检查是否设置了$ db变量,如果没有,则创建连接,并始终在文件末尾结束连接。

答案 2 :(得分:1)

我假设您在调用db_connect的每个位置使用相同的用户名/密码打开与同一数据库的连接。这样做时,除非你的db_connect显式指定,你正在创建一个新的链接,它将返回一个已打开的链接。如果该链接然后使用db_close()关闭,它也将关闭另一个连接,因为链接是相同。如果您使用mysql_connect连接到数据库,则需要一个名为new link

的参数

new_link 如果使用相同的参数对mysql_connect()进行第二次调用,则不会建立新的链接,而是返回已打开的链接的链接标识符。 new_link参数修改了这种行为,并使mysql_connect()始终打开一个新的链接,即使之前使用相同的参数调用了mysql_connect()。在SQL安全模式下,将忽略此参数。

请参阅http://php.net/manual/en/function.mysql-connect.php

我不确定这是否是你所面临的问题。希望它有所帮助。