我已经在这方面挣扎了很长一段时间,而且我需要寻求帮助,因为即使我完成了所有的研究,我也能做到这一点。 t了解为什么会发生这种情况。
致命错误:未捕获的异常' PDOException'消息' SQLSTATE [HY000] [1040]连接太多'
加载单个页面(index.php
)时会发生这种情况,我是唯一的用户(dev)。正如你在这里看到的那样,MySQL连接限制设置为@ 50,但我差不多超过了它。这是对重构代码之前创建的100个连接的改进。
以下是页面加载一次后的统计信息。
我已将问题缩小到几个原因:
我发现的大多数SO问题都告诉OP增加连接限制,而不是真正知道这是否是最好的解决方案,所以我试图在这里避免这种情况,如果它&#39 ;不需要。一页加载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()
类。
class 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服务器有两个数据库,prod和dev。我想两者之间共享连接限制。但是,prod数据库获得的流量非常少,我没有看到这个错误。当我刷新统计数据时,没有与prod数据库的连接。
答案 0 :(得分:0)
From the PHP manual ~ http://php.net/manual/en/pdo.connections.php
Many web applications will benefit from making persistent connections to database servers. Persistent connections are not closed at the end of the script, but are cached and re-used when another script requests a connection using the same credentials.
So I would advise removing the DbConnection#close()
method as you would not want to ever call this.
Also from the manual...
Note:
If you wish to use persistent connections, you must setPDO::ATTR_PERSISTENT
in the array of driver options passed to thePDO
constructor. If setting this attribute withPDO::setAttribute()
after instantiation of the object, the driver will not use persistent connections.
So you'll want (at least)
new \PDO("mysql:host=127.0.0.1;dbname=" . DBNAME, DBUSER, DBPASS, [
PDO::ATTR_PERSISTENT => true
]);
You can also set your other connection attributes in the constructor.