【问题标题】:Do I need to close unused prepared statements?我需要关闭未使用的准备好的语句吗?
【发布时间】:2019-03-11 14:17:34
【问题描述】:

我开发了某种查询构建器,并且编写了一些测试来检查 QueryBuilder 是否构建了正确的查询。

所以我有一组自己编写的查询,它们是预期的查询,QueryBuilder 将产生。

在我看来,仅仅比较这些查询是不够的,还要测试这些查询是否由底层 DBMS 编译。

因此,我使用 PDO::Prepare(而 EmulationMode=off!),让 DBMS 检查我的预期查询。

这个 PHPUnit 测试非常简单:

/**
 * @dataProvider provideExpectedSQLResults
 */
public function testExpectedSQLResults(string $sql)
{
    $this->getPdo()->prepare($sql);
}

这样我什至可以检查我的 QueryBuilder 是否正确(未)命名参数。

现在我的问题:

我是否必须“清理”所有这些打开的准备好的语句?

【问题讨论】:

  • PHP 会在每次脚本终止时为您执行此操作。
  • 在纯 PHP 中,您会返回一个 PDOStatment 对象来跟踪它们。所以 PHP 作为一个整体不会为你做这些。所以答案是不用担心他们。
  • 使用应该在__destruct()方法中添加public function __destruct(){ $this->getPdo()->close() }
  • 我认为您将准备好的语句与打开的数据库连接混淆了。 PDO 中没有打开或关闭的准备好的语句,我不知道 My QueryBuilder 是什么意思......但我可以在你的 testExpectedSQLResults 方法中告诉你,你不会执行该查询,因为你不从PDO::prepare返回语句对象
  • 一旦您的语句句柄/对象超出范围,PHP 垃圾收集器就会启动。

标签: php pdo prepared-statement


【解决方案1】:

正如我在 cmets 中所说的。

我认为您将打开的数据库连接与准备好的语句混淆了。对于准备好的语句 PDO 返回一个 PDOStatment 对象,您需要在其上调用执行。事实上 PDO 甚至没有执行方法。

http://php.net/manual/en/class.pdo.php

此外,没有开放式或封闭式准备语句之类的东西。

在您的示例代码中:

public function testExpectedSQLResults(string $sql)
{
    $this->getPdo()->prepare($sql);
}

这本质上是没有意义的(除非你只是为了抛出一个异常,这仍然主要是没有意义的,见下文)因为你永远不能执行这个查询,因为你没有返回实际具有执行方法的 PDOStatment 对象。

在数据库连接的情况下,通常你也不必担心这个

对于测试 PDO::prepare 确实返回布尔值 false 或抛出异常,具体取决于其设置方式。源代码中(通常)不存在参数化数据。它取决于应用程序运行时的状态。如果你愿意,输入数据。没有这个就没有办法真正测试它。

基本上,您在上面所做的只是测试 SQL 的语法,这通常是好是坏,并​​且不会根据用户输入发生太大变化。即使是动态查询也会起作用或不起作用,因为您的 SQL 要么在语法上正确,要么不正确。如果不是,您将不得不更改生成它的代码,您会在开发它时发现一些东西。

如果您使用 PHPUnit 之类的东西,单元测试是另一回事。您可以在哪里使用固定装置和模拟输入数据等。这更多地用于针对已知用例测试您的代码,因此如果您在此处进行代码更改,您不会突然在那里出现错误。等等。这是你可以调查的。你没有在问题中提到它,所以我只是假设你没有使用它。

在 PHPUnit 中,您可以测试此测试方法是否抛出特定异常,例如使用注释:

/**
 * @expectedException \PDOException
 */

https://phpunit.readthedocs.io/en/8.0/index.html

希望对您有所帮助。

【讨论】:

  • 您好,我将我的问题限制在基本问题上,并解释了与我的问题相关的所有内容。您对 PHPUnit 的引用与我的问题无关,而且与我想要的完全相反。
  • 关于“打开”/“关闭”:我不知道正确的英文术语,但你肯定有一个已经解析的语句,你只在执行时提交参数。这样它是“开放的”,这可能只意味着“准备好”。
猜你喜欢
  • 2012-03-20
  • 1970-01-01
  • 2018-09-26
  • 1970-01-01
  • 1970-01-01
  • 2019-07-03
  • 2011-10-01
  • 2011-09-08
相关资源
最近更新 更多