【问题标题】:mysql_real_escape_string with singleton database in php?mysql_real_escape_string 与 php 中的单例数据库?
【发布时间】:2012-04-21 17:20:54
【问题描述】:

我在使用数据库函数的 php 页面上收到以下错误:

警告:mysql_real_escape_string() [function.mysql-real-escape-string]:用户访问被拒绝 'apache'@'localhost'

我知道我必须与我的数据库建立有效的连接,但这是“问题”。连接到我的数据库的类如下所示:

class Database
{
    private static $instance = null;
    private static $conn;

    private function __construct()
    {
        try {
            self::$conn = new mysqli('localhost', 'root', 'user', 'database');
        } catch (Exception $ex) {
            $errorpager = new CustomPageGenerator();
            $errorpager->generateErrorPage("Connection to database failed. Please try again later.");
        }
    }

    public static function getInstance()
    {
        try {
            if (self::$instance == null) {
                self::$instance = new Database();
            }
            return self::$instance;
        } catch (Exception $ex) {
            $errorpager = new CustomPageGenerator();
            $errorpager->generateErrorPage("Connection to database failed. Please try again later.");
            return false;
        }
    }

    public function query($sql)
    {
        try {
            return self::$conn->query($sql);
        } catch (Exception $ex) {
            $errorpager = new CustomPageGenerator();
            $errorpager->generateErrorPage("Connection to database failed. Please try again later.");
            return false;
        }
    }
}

如您所见,我为此使用了单例模式。但即使我放了一个

Database::getInstance();

在我的代码一开始打开连接时,我不断收到此错误。如何正确打开连接以便可以使用 mysql_real_escape_string() 函数?

谢谢。

这里是修复

在数据库类中添加了这个函数:

public static function getConnection()
{
    self::getInstance();
    return self::$conn;
}

将每一个 mysql_real_escape_string( 替换为 mysqli_real_escape_string(Database::getConnection(),

【问题讨论】:

  • 首先mysqli的函数调用中缺少),表示没有建立与数据库的连接。使用 new mysqli('localhost', 'root', 'user', 'database'); 连接到数据库时是否遇到任何错误
  • 是的,那是因为我“审查”了我的真实用户名和密码并意外删除了一个 )。修复了该错误。
  • 使用new mysqli('localhost', 'root', 'user', 'database'); 连接数据库时是否遇到任何错误?
  • 不。奇怪的是:例如,我有一个向我的网站注册新用户的功能。我可以填写注册表,按下注册按钮,然后获取这些错误的列表。但是当我用 phpmyadmin 查看我的数据库时,有一个新行,但所有列都是空的。
  • MysqliMysql 使用可能是问题的不同连接。使用mysqli连接数据库时,不能使用mysql_real_escape_string()

标签: php mysql database


【解决方案1】:

我认为问题在于您使用的是mysql_real_escape_string()

那来自与mysqli 不同的库,也许这就是没有连接的原因?

来自mysql_real_escape_string page in the PHP manual

string mysql_real_escape_string (string $unescaped_string [, 资源 $link_identifier = NULL ])

这是第二个参数$link_identifier的定义。

MySQL 连接。如果未指定链接标识符,则 假定由 mysql_connect() 打开的最后一个链接。如果没有这样的链接 找到,它将尝试创建一个,就好像 mysql_connect() 被调用 没有论据。如果没有找到或建立连接,则 E_WARNING 产生级别错误。


一个可能但有点丑陋的解决方案是在你的 db 单例中的 mysqli 实例上的 real_escape_string 方法中添加一个包装器。

public function escapeString($value){
    return $this->conn->real_escape_string($value);
}

另一种选择可能是使用 mysqli 库的程序版本(虽然,我实际上并没有尝试看看你是否可以混合使用两者,但我认为你可以):mysqli_real_escape_string

【讨论】:

  • 有没有办法可以改变我的数据库类?我有几十个 mysql_real_escape_string() 函数,但只有一个地方可以连接到我的数据库。
  • 如果您不想删除所有 mysql_real_escape_string 函数,可以尝试将调用更改为mysqli_real_escape_string。我还没有尝试过,但这可能会奏效。只要在调用之前建立了连接即可。可能不是在每个地方都有 mysql_real_escape_string 的最佳解决方案。但这可能是一个快速的解决方案。
  • 为了更好的解决方案,你可以从mysqli准备好的语句中取一个队列。看看你是否可以重构你的类来使用它。这样,您可以在查询执行期间将转义字符串功能移动到您的类中。 php.net/manual/en/mysqli-stmt.bind-param.php
  • 我可以尝试用 mysqli_... 替换所有 mysql_... 但这个函数需要 2 个参数。 1 个连接和 1 个要转义的字符串。这需要大量的重构(我们说的可能是几千行代码)。另外,我的 Database::getInstance() 函数不返回连接,它返回一个数据库实例。所以这意味着更多的重构:D我刚才才遇到这个问题,因为我的webhost抛出了这个问题,但我的开发环境没有。
  • 好点。我没有意识到mysqli版本。也许您可以将代码转换为使用 mysql 程序函数。它的工作原理几乎相同,只是它不是面向对象的。
猜你喜欢
  • 1970-01-01
  • 2011-01-02
  • 1970-01-01
  • 2017-11-20
  • 1970-01-01
  • 2014-07-31
  • 1970-01-01
  • 2011-02-19
  • 1970-01-01
相关资源
最近更新 更多