【问题标题】:closing PDO connections issue关闭 PDO 连接问题
【发布时间】:2014-04-24 22:01:29
【问题描述】:

我的 PDO 连接有问题! 我读到我不想关闭 PDO 连接,因为会自动关闭! 但是如果你想手动关闭它,我需要将 Null 分配给连接变量。 但我使用一个数据库类,数据库查询是这样运行的!

$addUser = users::getInstance()->userAdd($data);

和 users 类包含以下内容

class users extends DB {
private static $_instance = null;   
public static function getInstance(){

if (!isset(self::$_instance)){
    self::$_instance = new users();
}
return self::$_instance;
} 
 [...]
 }

和数据库类

    class DB {

    private static $_instance = null;
    private $_con;
        [...]

    public function __construct(){
        try{
    $this->_con = new PDO('mysql:host=localhost';dbname=db,user,pass);  
        }catch(PDOException $e){
            die ($e->getMessage());
        }
    } 

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

public static function getInstance(){
    if (!isset(self::$_instance)){
        self::$_instance = new DB();
    }
    return self::$_instance;
}

public function close(){
    $this->_con = null;
}
[...] }

问题是脚本没有关闭连接,因为当我限制本地主机中的最大用户连接数或使用已经限制它的免费网络主机服务时,我收到此错误消息

SQLSTATE[HY000] [1203] User 'userName' already has more than 'max_user_connections' active connections

我需要一个解决方案,通过在我使用实例方法建立连接时关闭连接来避免此错误消息!

【问题讨论】:

    标签: php mysql database pdo


    【解决方案1】:
    1. 摆脱 DB 类。
    2. 不要从 DB 类扩展应用程序类。
    3. 不要玩静态魔法。
    4. 创建原始 PDO 对象并将其传递到应用程序类中
    5. 忘记这个连接的东西

    原来如此:

    $pdo  = new PDO('mysql:host=localhost;dbname=db','user','pass');    
    $user = new users($pdo);
    $user->select();
    
    class users
    {
        protected $db;
    
        function __construct($pdo){
            $this->db = $pdo;
        }
        function select()
        {
            $this->db->query("select 1");
        }
    }
    

    这样,每个脚本实例只会创建 一个 连接,您将永远不会再遇到此类错误。

    【讨论】:

    • 如果我想将$pdo 传递给特定类的构造函数并在那里共享它而不使用global,那么如何使用它?使用 DI 容器时会返回错误。
    • 只需将 $pdo 传递给构造函数并将其分配给局部变量
    • 来吧。将 $pdo 传递给构造函数并将其分配给局部变量是 DI。怎么不行?
    • 这就是我问自己的问题。我收到奇怪的警告Warning: Missing argument 2 for Database::__construct(),然后是Notice: Undefined variable: pdo in。如果我做同样的事情但在构造函数中使用global $pdo - 那么它可以工作。为什么会发生这种情况?顺便说一句,我正在使用 Dice DIC (r.je/dice.html)。
    • 只是为了减少混淆:DIC 不是 DI。是的,您必须为 DIC 设置规则
    【解决方案2】:

    我把这个留在这里是为了提醒我在发布“不太有用”的答案之前先考虑一下。 ;-/

    请将“您的常识”提供的答案与全局、重复使用的连接结合使用。

    不要继续阅读...

    停止丢弃未使用的连接!让它们保持活跃!

    完成“连接”后,将其返回到“空闲列表”数组。不要破坏它

    1) 当您需要新的数据库连接时,请检查“空闲列表”。如果有的话,请拿上免费的。

    2) 如果没有免费的可用,创建一个并使用它。

    3) 完成后将其放入空闲列表。不要关闭它!

    将“空闲列表”实现为“堆栈”。我还保留了“活动连接列表”。当一个完成时,只需将其返回到“空闲列表”。

    这很有效

    您可能会用完“数据库句柄”,但您需要十个活动的重叠活动事务。

    【讨论】:

    • PHP 中没有“免费列表”之类的东西
    • @Your 常识,好的,我同意,我应该将其明确编码为一个类,该类负责处理与所需数组的打开连接。我很懒惰。
    • 看,你把 PHP 看错了。没有也不应该有类似连接列表的东西,无论是“空闲列表”还是“必需数组”。 PHP 脚本运行 lice 一个 cli 程序 - 策略、运行和死亡。没有环境可以为它保存连接池 - 无论是内部还是外部。每个 PHP 实例只能打开一个全新的连接,直接连接到数据库,没有任何列表。
    • 并且 PHP 脚本实例本身也不应该拥有连接池。它的执行是线性的,因此只有一个连接是没有用的。并且为了性能起见,应该始终只有一个连接
    • 对上下文不敏感的挑剔者的免责声明:我很清楚持久连接和具有不同凭据的多个连接 - 可能比你更清楚。这里不是这样。
    猜你喜欢
    • 2013-08-19
    • 1970-01-01
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-20
    相关资源
    最近更新 更多