PHP,变量范围问题

发布于 2024-11-03 08:45:00 字数 1137 浏览 0 评论 0原文

我的问题是我在我的通用脚本代码和我的函数之一中使用变量 $db 。它的目的是成为用于 MySQL 连接的变量。我需要在函数内部将一些数据写入数据库。在我的脚本中,我不能假设现有的数据库连接将打开,因此我打开一个新连接并在函数退出之前将其关闭。自从执行此操作后,我在脚本运行后收到一条错误消息,提示 MySQL 引用错误/不存在。

我唯一可以将其固定到的是在我的核心代码中,我使用变量 $db 作为数据库连接的变量名称。我还在函数中使用相同的变量。我没想到这会成为问题,因为我没有在函数中的 $db 前面使用 global 。这应该意味着我在函数中引用的 $db 位于函数私有范围内,但它似乎正在关闭公共 $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);
}

ma​​in.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)

My question is I am using the variable $db in my general script code and within one of my functions. It's purpose is to be the variable that is used for MySQL connections. I have a need inside a function to write some data to the database. In my script I cannot assume that an existing db connection will be open so I open a new one and close it before the function exits. Ever since doing this I am getting an error after the script runs saying the MySQL reference is bad / doesn't exist.

The only thing I can pin it to is in my core code I use the variable $db as the variable name for database connection. I also use the same variable in the function. I did not imagine this would be a problem because I do not use global in front of $db in the function. This should mean the $db I reference in my function is in the functions private scope but it seems to be closing the public $db's connection.

Any thoughts?

Fragments of my code are:

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小耗子 2024-11-10 08:45:00

要管理数据库连接,您可以创建一个类而不是一对函数。如果您说“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(它是,但只是在技术意义上)。上面的内容不太适合单元测试。如果您想要一种更加面向对象的方法(这将更适合单元测试),请扩展或包装 PDO。使用依赖注入也可以帮助上述的耦合问题。

To manage DB connections, you can create a class rather than a pair of functions. If where you say "MySQL reference", the exact error refers to a "MySQL resource", then you are using the outdated mysql extension and should switch to a more modern extension, such as 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 */
    }
}

Note that this isn't exactly OOP (it is, but only in a technical sense). The above doesn't lend itself well to unit testing. If you want a more OO approach (which will be more amenable to unit testing), extend or wrap PDO. Using dependency injection can also help with the coupling issues of the above.

ヅ她的身影、若隐若现 2024-11-10 08:45:00

我假设您在调用 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

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

I assume you are opening a connection to the same database with the same username/password at each of the places you call db_connect. When doing so,unless your db_connect explicitly specifies, that you are creating a new link, it will return an already opened link.If that link is then closed using db_close(), it will also close the other connection, since the link is the same. If you are using mysql_connect to connect to the database, it takes an argument called new link

new_link
If a second call is made to mysql_connect() with the same arguments, no new link will be established, but instead, the link identifier of the already opened link will be returned. The new_link parameter modifies this behavior and makes mysql_connect() always open a new link, even if mysql_connect() was called before with the same parameters. In SQL safe mode, this parameter is ignored.

Refer to http://php.net/manual/en/function.mysql-connect.php

I'm not sure if this is the issue you are facing. Hope it helps.

薄暮涼年 2024-11-10 08:45:00

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

I would assume what is happening is the connect cancels out because there already is a connection, and then the close ends the current connection.
I would recommend either A) start a connection at the beginning of the file, and just know it's always there (what I do); or B) check the to see if the $db variable is set, if not then create the connection, and always end the connection at the end of the file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文