我一直在挣扎与此相当长一段时间,它的的地方,我需要寻求帮助,因为即使所有的研究,我已经做了我不能让上为什么会这样一个手柄点。
致命错误:未捕获的异常“PDOException”与消息“SQLSTATE [HY000] [1040]连接太多”
这发生在加载一个页面(index.php
),我唯一的用户(DEV)。正如你可以在这里看到,MySQL连接限制设置@ 50,但我勉强赶超。这是在之前我重构代码,正在创建的100〜连接的改善。
以下是在页面加载一次之后的统计数据。
我已经收窄的问题到几个原因:
大部分时间我已经找到了做题,告诉OP增加连接限制,而不真正知道如果这是这样,我想避免的是,这里如果不需要它的最佳解决方案。对于一个页面加载50个连接看起来方式太多了。
这些都是我在问题页面上实例化的类。
$DataAccess = new \App\Utility\DataAccess();
$DataCopyController = new App\Controllers\DataCopyController($DataAccess);
$DriveController = new App\Controllers\DriveController($DataAccess);
$Helper = new App\Utility\Helper();
$View = new App\Views\View();
我创建了DAL对象,然后将它注入需要它的类。通过做这种方式,我希望只创建一个对象和一个连接,但是这不是发生了什么很明显。里面的DAL类我还添加了$this->DbConnect->close()
到每一个查询方法。
下面是DataAccess()
类的构造函数。
public function __construct() {
$this->DbConnect = new \App\Services\DbConnect();
$this->db = $this->DbConnect->connect("read");
$this->dbmod = $this->DbConnect->connect("write");
$this->Helper = new Helper();
}
这里是DbConnect()
类。
一流的数据库连接{
private $db;
private $dbmod;
private function isConnected($connection) {
return ($connection) ? TRUE : FALSE;
}
public function connect($access) {
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false
];
if ($access == "read") {
if ($this->isConnected($this->db)) {
return $this->db;
} else {
if (strpos($_SERVER['SERVER_NAME'], DBNAME_DEV) === false) {
$this->db = new PDO("mysql:host=127.0.0.1; dbname=".DBNAME,
DBUSER,
DBPASS,
$options
);
} else {
$this->db = new PDO("mysql:host=" . DBHOST_DEV ."; dbname=".DBNAME_DEV,
DBUSER,
DBPASS,
$options
);
}
return $this->db;
}
} elseif ($access == "write") {
if ($this->isConnected($this->dbmod)) {
return $this->dbmod;
} else {
if (strpos($_SERVER['SERVER_NAME'], DBNAME_DEV) === false) {
$this->dbmod = new PDO("mysql:host=127.0.0.1; dbname=".DBNAME,
DBUSER_MOD,
DBPASS,
$options
);
} else {
$this->dbmod = new PDO("mysql:host=" . DBHOST_DEV . "; dbname=".DBNAME_DEV,
DBUSER_MOD,
DBPASS,
$options
);
}
}
return $this->dbmod;
}
}
public function close() {
$this->db = null;
$this->dbmod = null;
}
}
我也尝试实例上DbConnect()
的index.php
类和注射,与其DataAccess()
但结果是一样的。
编辑:我也想补充一点,这个MySQL服务器有两个数据库,督促和开发。我想连接限制在两者之间共享。然而,督促数据库中获取流量很少,我没有看到这样的错误。当我刷新了统计,有以督促数据库的连接。
从PHP手册〜http://php.net/manual/en/pdo.connections.php
许多Web应用程序将受益于制作到数据库服务器的持久连接。持久连接不关闭在脚本的末尾,但缓存,当另一个脚本请求使用相同的凭据连接重新使用。
所以,我建议去掉DbConnection#close()
方法,你不会想调用过这一点。
此外,从手动...
注意: 如果你想使用永久连接,您必须传递给
PDO::ATTR_PERSISTENT
构造驱动选项数组中设置PDO
。如果对象实例化后设置与PDO::setAttribute()
此属性,驱动程序将不会使用持久连接。
所以,你会希望(至少)
new \PDO("mysql:host=127.0.0.1;dbname=" . DBNAME, DBUSER, DBPASS, [
PDO::ATTR_PERSISTENT => true
]);
您还可以设置在构造函数中的其他连接属性。