Mysql表示超出了用户最大连接数

时间:2014-01-10 18:34:10

标签: php mysqli statements

我有一个CMS在多个人登录时失败。我认为问题可能是我没有正确关闭数据库。以下是基本设置:

我有一个名为Mysql的大师班。 __construct()方法如下所示:

class Mysql {

    protected $conn;

    function __construct() {

        if(!$this->conn) $this->conn = New mysqli(SITE_HOSTNAME, SITE_USERNAME, SITE_PASSWORD, SITE_DATABASE);

}

我的所有类都是这个类的后代,所以每当它们被实例化时,它们都会得到自己的连接。

我正在使用预准备语句来防止sql注入。示例方法可能如下所示:

function foo($blog = 0) {

    $query = "SELECT catid, catname
              FROM category
              WHERE blog = ?
              ORDER BY catname ASC";

    $result = array();
    if($stmt = $this->conn->prepare($query)) {
        $stmt->bind_param('i', $blog);
        $stmt->execute();
        $stmt->bind_result($catid, $catname);
        while($stmt->fetch()) $result[$catid] = stripslashes($catname);
        $stmt->close();
        return $result;
    }

}

Mysql __destruct()方法如下所示:

function __destruct() {
    if($this->conn) $this->conn->close();
}

我的问题是我没有正确关闭我的连接,或者我没有足够的活动连接?

我的提供商说我有30个可用的同时连接。还不够吗?

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

问题

  

我的所有课程都是这门课程的后代,所以无论什么时候   实例化,他们得到自己的联系。

您执行此操作的方式的问题是,继承Mysql的任何类的每个实例都打开与Mysql服务器的连接,该服务器一直存在,直到请求完成,或者变量destructed(除非你手动杀死这些对象,这是在请求的最后)。如果您有30个这样的类实例,那么您已经最大化了连接。

解决问题

您的类不应该都继承这个代表数据库接口的Mysql类。

相反,您应该在需要的地方传递此Mysql类的单个实例。

有两种方法可以有效地完成:

依赖注入

class SomeClass {
    protected $db;

    public function __construct(Mysql &$db) {
        $this->db = $db;
    }

    public function functionThatNeedsDatabase() {
        $this->db->doSomethingWithTheDatabase();
    }
}

$db = new Mysql(); //A single instance of Mysql class has been created.
$someClass = new SomeClass($db);
$someClass->functionThatNeedsDatabase();

需要时传递给方法

class SomeClass {
    public function functionThatNeedsDatabase(Mysql &$db) {
        $db->doSomethingWithTheDatabase();
    }
}

$db = new Mysql(); //A single instance
$someClass = new SomeClass();
$someClass->functionThatNeedsDatabase($db);

答案 1 :(得分:1)

你的问题是“我的所有类都是这个类的后代,所以每当它们被实例化时,它们就会得到自己的连接。”在PHP中,脚本结束时会自动关闭连接。你真的只需要每个用户1个连接。您应该创建一个DB类的实例,并将该对象传递给需要使用它的所有类(依赖注入模式)。

30个连接不是很多,但这足以满足大量流量。我会避免使用持久连接。请仔细阅读文档,有很多警告。