我已经被这个错误难倒了好几天了,我找不到修复它的方法。我试图实现
- 单一实例数据库对象
- 查询后关闭我的连接
- 尝试持久性连接
- 将最大连接数设置为 250(本地)
- 设置最大用户连接数 250(本地)
这发生在其他人身上吗?
奇怪的是我的本地服务器上的错误消息Connection failed: SQLSTATE[08004] [1040]
,但行仍在插入并且数据库查询有效。
在生产服务器上,错误消息变为Connection failed: SQLSTATE[42000] [1203] User db_admin already has more than 'max_user_connections' active connections
我知道最大连接数设置为 15,但我已经咨询了支持人员,他们说在发生此错误时我没有连接。
在我的所有选项之后,有人可以检查我的代码以确保其中没有可能产生这些错误的错误吗?
class MyPDO extends PDO{
const DB_HOST='localhost';
const DB_PORT='3306';
const DB_NAME='db_name';
const DB_USER='db_admin';
const DB_PASS='SECRET';
public function __construct(){
parent::__construct('mysql:host='.MyPDO::DB_HOST.';port='.MyPDO::DB_PORT.';dbname='.MyPDO::DB_NAME,
MyPDO::DB_USER,MyPDO::DB_PASS);
try{
$this->db = new MyPDO();
$this->db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
}catch(PDOException $e){
//always catching the connection errors
echo 'Connection failed: ' . $e->getMessage();
}
}
public function query($query){
$args = func_get_args();
array_shift($args);
//check inputs
var_dump($args);
$reponse = parent::prepare($query);
$reponse->execute($args);
return $reponse;
}
}
这是插入查询
function InsertUserToSql()
{
$ret = $this->db->query("INSERT INTO CD_USERS (email,username,password,fname,lname,dob,gender) VALUES
(?,?,?,?,?,?,?)",$this->Email,$this->Username,$this->Password,$this->Fname,
$this->Lname,$this->Birthday,$this->Gender);
if($ret){
echo "insert success";
return $this->db->lastInsertId();
}
$this->db = null;
}
不要扩展PDO
,实际上,永远不要扩展你不拥有的对象。扩展PDO
对于最终使用您的代码的人来说很烦人,这是完全没有意义的(你想做什么?改进清晰且众所周知的 PDO API?或者创建一个更适合您当前需求的对象 - 这意味着:创建一个您将无法再次使用的对象,这违背了 OOP 的观点)?我已经有很多原因,为什么你不应该从这里延伸PDO
,可能值得一看。
您的实际问题:
不要在类自己的构造函数中创建类的新实例!
在 MyPDO
构造函数中创建新MyPDO
将再次调用 MyPDO
构造函数,这将创建一个新的 MyPDO
实例,该实例将再次调用 MyPDO
构造函数,这将创建一个新的 MyPDO
实例,这将再次调用MyPDO
构造函数,这将...
这是无限递归在起作用。
可以这样想:如果有人告诉你:
"如果你把右脚移到左脚前面,你必须再次把右脚移到左脚前面"
然后,那个带着行走固定的虐待狂疯子会指示你(在枪口下):
"现在把右脚放在左脚前面"
你需要多长时间才能完成你的大ecart(或分裂),并且不能再进一步了。这就是代码中发生的情况。
而且,稍微跑题了,如果你遇到一个问题,并试图用 PHP 中的单例来解决它,你就引入了一个新问题......
你有递归代码:一个实例在 $this->db
中创建一个新实例,这会在其$this->db
中创建一个新实例,进而创建另一个实例,依此类推,直到最深的实例抛出错误(或者你超过了 PHP 中的最大嵌套深度(不是在 vannilla 中,但某些模块(Zend,xdebug)设置了限制), 以先到者为准),并且您最多只剩下成功了 N 个实例,从您的代码来看,您可能只使用第二个实例(如果MyPDO extends PDO
,您可以只调用 $this->query()
,->db
中不需要另一个实例,并使用 $this->db->query()
。