【问题标题】:Properly closing database connections in PHP在 PHP 中正确关闭数据库连接
【发布时间】:2012-02-28 01:21:33
【问题描述】:

我在 PHP 数据库连接方面遇到了一些疑问。由于我不能只在我的方法(Java 风格)上放置一个大的 try/catch/finally 块,当大小/逻辑趋于增加时,正确关闭所有连接和准备好的语句的最佳方法是什么?考虑下一个方法,一切都做对了吗?

public function createRegister($register) {
        $this->openConnection();

        $query = "INSERT INTO register (username, password, email, confirmationToken) VALUES (?, ?, ?, ?)";
        $result = $this->mysqli->query($query);

        if ($statement = $this->mysqli->prepare($query)) {  
            $statement->bind_param("ssss", $register->username, $register->passwordHash, $register->email, $register->confirmationToken);

            if (!$statement->execute()) {
                $this->closeConnection();
                throw new DAOException("Failed to execute statement: " . $statement->error);
            }

            $statement->close();

        } else {
            $this->closeConnection();
            throw new DAOException("Failed to prepare statement: " . $this->mysqli->error);
        }

        $this->closeConnection();
    }

【问题讨论】:

  • 您真的要为每个查询打开/关闭连接吗?为什么要混合不同层的代码?您应该将查询执行封装到一个单独的函数中..
  • @yi_H:好点。在我的回复中,我提到了通过单例/工厂模式回收连接的能力。

标签: php database connection mysqli prepared-statement


【解决方案1】:

你仍然可以在 PHP 中使用 try/catch:

public function createRegister($register) {

    $this->openConnection();

    $query = "INSERT INTO register (username, password, email, confirmationToken) VALUES (?, ?, ?, ?)";

    try {

        // This line is not needed
        // $result = $this->mysqli->query($query);

        if ($statement = $this->mysqli->prepare($query)) {

            $statement->bind_param("ssss", $register->username, $register->passwordHash, $register->email, $register->confirmationToken);

            if (!$statement->execute()) {                   
                throw new DAOException("Failed to execute statement: " . $statement->error);
            }

            $statement->close();

        } else {
            throw new DAOException("Failed to prepare statement: " . $this->mysqli->error);
        }
    } catch (Exception $e) {

        if ((isset($statement)) && (is_callable(array($statement, 'close')))) {
            $statment->close();
        }

        $this->closeConnection();

        throw $e;
    }

    $this->closeConnection();
}

这对于为一项特定任务建立连接非常有效,但是如果您想为同样需要访问同一架构的多个任务共享同一连接怎么办?您可能需要考虑使用单例/工厂模式来创建和访问数据库连接的更高级的解决方案。我发布了这样一个example 作为另一个问题的解决方案。它更高级一些,但一旦你开始了解它,它的性能就会更高。

【讨论】:

  • 我应该在哪里正确关闭我的 $statement?
  • @Rui:你最后做了什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-30
  • 1970-01-01
  • 1970-01-01
  • 2017-07-08
  • 1970-01-01
  • 2012-03-29
  • 2012-04-10
相关资源
最近更新 更多