Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php PDO闭合连接_Php_Pdo - Fatal编程技术网

Php PDO闭合连接

Php PDO闭合连接,php,pdo,Php,Pdo,与MySQLi相比,PDO只是一个相当简单的问题 使用MySQLi,要关闭连接,可以执行以下操作: $this->connection->close(); 但是,对于PDO,它表示您使用以下方式打开连接: $this->connection = new PDO(); 但要关闭连接,请将其设置为null $this->connection = null; 这是否正确?这是否会释放PDO连接?(我知道设置为null)我的意思是,使用MySQLi,您必须调用函数(clos

与MySQLi相比,PDO只是一个相当简单的问题

使用MySQLi,要关闭连接,可以执行以下操作:

$this->connection->close();
但是,对于PDO,它表示您使用以下方式打开连接:

$this->connection = new PDO();
但要关闭连接,请将其设置为
null

$this->connection = null;

这是否正确?这是否会释放PDO连接?(我知道设置为
null
)我的意思是,使用MySQLi,您必须调用函数(
close
)来关闭连接。PDO是否像断开连接一样容易?或者是否有关闭连接的功能?

根据文档,您是正确的():

连接在该PDO对象的生存期内保持活动状态。到 关闭连接时,您需要通过确保 对它的所有剩余引用都将被删除--您可以通过分配 包含对象的变量为NULL。如果你不这样做 显式地,PHP将在 脚本结束


请注意,如果您将PDO对象初始化为持久连接,它将不会自动关闭连接。

我创建了一个派生类,以拥有一个更自我记录的指令,而不是
$conn=null

$conn=new PDO("mysql:host=$host;dbname=$dbname",$user,$pass);
    // If this is your connection then you have to assign null
    // to your connection variable as follows:
$conn=null;
    // By this way you can close connection in PDO.
class CMyPDO extends PDO {
    public function __construct($dsn, $username = null, $password = null, array $options = null) {
        parent::__construct($dsn, $username, $password, $options);
    }

    static function getNewConnection() {
        $conn=null;
        try {
            $conn = new CMyPDO("mysql:host=$host;dbname=$dbname",$user,$pass);
        }
        catch (PDOException $exc) {
            echo $exc->getMessage();
        }
        return $conn;
    }

    static function closeConnection(&$conn) {
        $conn=null;
    }
}
因此,我可以在以下两种情况之间调用我的代码:

$conn=CMyPDO::getNewConnection();
// my code
CMyPDO::closeConnection($conn);

它不仅仅是将连接设置为null。这可能是文档中所说的,但对于mysql来说并非如此。连接将保持更长时间(我听说是60年代,但从未测试过)

如果您想在这里看到完整的解释,请参阅此连接上的注释

要强制关闭连接,必须执行以下操作

$this->connection = new PDO();
$this->connection->query('KILL CONNECTION_ID()');
$this->connection = null;


我询问的原因是我不确定是否正确关闭了连接。但是没有,不仅仅是有趣的,当你的PHP脚本停止执行时,数据库连接会自动关闭。如果你已经使用完它,为什么不继续并终止它,尤其是当你完成与数据库的交互后,如果有一些耗时的代码的话。不过,我也不认为等待脚本完成会有什么问题(除了减少与DB服务器的连接)。自己看看它是如何工作的:PNot所有的php脚本都是短期的。这里有php守护进程。我认为这是一件很好的事情,我个人需要澄清。如果我有一个没有结束的过程呢?e、 g.websocket。有没有办法不使用持久连接?对于长时间运行的脚本中的持久连接,您可以故意(或意外)让连接因超时(例如在my.ini中)或其他原因而终止。连接或运行查询时,捕获任何错误,如果是“MySQL已消失”,再次尝试连接或再次运行查询。
请注意,如果将PDO对象初始化为持久连接,它将不会自动关闭连接
,但是如果连接是持久连接,并且我在脚本结束前显式调用NULL,它将关闭,即使它是持久连接,对吗?@tonix No,它应该被发布(可供其他脚本使用),但不能关闭。@tonix我想是的。引自:“警告:在使用持久连接时,需要记住几个额外的注意事项。一种是,在持久连接上使用表锁定时,如果脚本出于任何原因无法释放锁,那么使用相同连接的后续脚本将无限期地阻塞,并且可能需要重新启动httpd服务器或数据库服务器。“我认为这是一种非常糟糕的模式,尤其是当开发人员可能存储pdo引用的多个副本时$a=新的PDO(…)$b=一美元$a=零;在那里,您的PDO对象将永远保持打开状态(在类似于php程序的守护进程中)。当PDO引用在函数和对象属性之间移动时尤其如此,并且您永远无法确定是否将它们全部清空。PDO上应该有一个->close()方法。不喜欢PDO的另一个原因。@Gabriel-我建议“存储多个副本”如果您在这两行之间创建了PDOStatement对象(也就是说,在每种实际情况下),这就不起作用。要关闭连接,必须将PDO对象和PDOStatement对象都设置为null。请看这里:您可以将CMyPDO::_construct()方法设为私有,并在那里使用单例模式。是的,这是可能的。如果一次使用多个数据库,还需要通过另一种方法分配连接信息。差别很小,只是调用实例方法的指令稍长。@AdityaHajare您不能在子类中将超类的公共方法设为私有。@nickdnk,您是对的。我的意思是创建一个独立的类CMyPDO(不使其扩展PDO),然后在CMyPDO(新PDO($dsn,$dbuser,$dbpass);)类的私有构造函数内创建一个数据库实例,确保整个应用程序中只有一个实例可用(单例设计模式)。@Fil但代码“外部”
closeConnection
不应意识到它需要复制对变量的引用,而不是分配对象。换句话说,您尝试编写封闭PDO函数的方法会产生不良副作用,使其不可靠。唯一的方法是
closeConnection
检查代码中存在多少对PDO对象的引用,如果存在多个引用,则抛出。谢谢您的回答。这个问题是很久以前提出来的,但是你对连接的看法是正确的。我并不认为通过PHP破坏TCP连接是个好主意。所有底层TCP连接处理都被抽象掉了,因此我们只需要在运行时处理高层类和对象。PHP是一种基于请求的语言(正如您可能知道的),因此终止与dB的潜在持久性连接将非常有用
<?php if(!class_exists('PDO2')) {
    class PDO2 {
        private static $_instance;
        public static function getInstance() {
            if (!isset(self::$_instance)) {
                try {
                    self::$_instance = new PDO(
                        'mysql:host=***;dbname=***',
                        '***',
                        '***',
                        array(
                            PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_general_ci",
                            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION
                        )
                    );
                } catch (PDOException $e) {
                    throw new PDOException($e->getMessage(), (int) $e->getCode());
                }
            }
            return self::$_instance;
        }
        public static function closeInstance() {
            return self::$_instance = null;
        }
    }
}
$req = PDO2::getInstance()->prepare('SELECT * FROM table');
$req->execute();
$count = $req->rowCount();
$results = $req->fetchAll(PDO::FETCH_ASSOC);
$req->closeCursor();
// Do other requests maybe
// And close connection
PDO2::closeInstance();
// print output