Php 我是否需要关闭未使用的准备好的报表?

Php 我是否需要关闭未使用的准备好的报表?,php,pdo,prepared-statement,Php,Pdo,Prepared Statement,我开发了某种查询生成器,并编写了一些测试来检查QueryBuilder是否构建了正确的查询 因此,我有一组自编查询,它们是QueryBuilder将生成的预期查询 在我看来,仅仅比较这些查询是不够的,还要测试这些查询是否由底层DBMS编译 因此,我使用PDO::Prepare(而仿真模式=off!),让DBMS检查我的预期查询 这个PHPUnit测试非常简单: /** * @dataProvider provideExpectedSQLResults */ public function t

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

因此,我有一组自编查询,它们是QueryBuilder将生成的预期查询

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

因此,我使用
PDO::Prepare
(而仿真模式=off!),让DBMS检查我的预期查询

这个PHPUnit测试非常简单:

/**
 * @dataProvider provideExpectedSQLResults
 */
public function testExpectedSQLResults(string $sql)
{
    $this->getPdo()->prepare($sql);
}
这样,我甚至可以检查QueryBuilder是否正确(取消)命名参数

现在我的问题是:


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

正如我在评论中所说的那样

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

此外,不存在开放式或封闭式准备声明

在您的示例代码中:

public function testExpectedSQLResults(string $sql)
{
    $this->getPdo()->prepare($sql);
}
这本质上是没有意义的(除非您只是为了抛出一个异常而这样做,这仍然是没有意义的,请参见下文),因为您永远无法执行此查询,因为您不会返回实际具有execute方法的pdostation对象

在DB连接的情况下,通常您也不必担心这一点

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

基本上,您在上面所做的只是测试SQL的语法,它通常是好的还是坏的,并且不会根据用户输入进行太多更改。即使是动态查询也会起作用,因为您的SQL要么语法正确,要么语法错误。如果不是这样,您将不得不更改生成它的代码,在开发过程中您将发现这一点

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

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

/**
 * @expectedException \PDOException
 */


希望这能有所帮助。

正如我在评论中所说

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

此外,不存在开放式或封闭式准备声明

在您的示例代码中:

public function testExpectedSQLResults(string $sql)
{
    $this->getPdo()->prepare($sql);
}
这本质上是没有意义的(除非您只是为了抛出一个异常而这样做,这仍然是没有意义的,请参见下文),因为您永远无法执行此查询,因为您不会返回实际具有execute方法的pdostation对象

在DB连接的情况下,通常您也不必担心这一点

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

基本上,您在上面所做的只是测试SQL的语法,它通常是好的还是坏的,并且不会根据用户输入进行太多更改。即使是动态查询也会起作用,因为您的SQL要么语法正确,要么语法错误。如果不是这样,您将不得不更改生成它的代码,在开发过程中您将发现这一点

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

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

/**
 * @expectedException \PDOException
 */


希望这会有所帮助。

PHP将在每次脚本终止时为您执行此操作。在普通PHP中,您将获得一个PDOStation对象来跟踪它们。所以PHP作为一个整体不会为您这样做。所以答案是不用担心它们。use应该在
\uuu destruct()
方法
公共函数\uu destruct(){$this->getPdo()->close()}
中添加这一点,我认为您将准备好的语句与打开的数据库连接混淆了。PDO中没有打开或关闭的预处理语句,我不知道我的QueryBuilder是什么意思。。。但是我可以告诉您,在您的
testExpectedSQLResults
方法中,您不会执行该查询,因为一旦您的语句句柄/对象超出范围,您不会从
PDO::prepare
返回语句对象,PHPs垃圾收集器将启动。PHP将在每次脚本终止时为您执行此操作。在普通PHP中,您将获得一个PDOStation对象来跟踪它们。所以PHP作为一个整体不会为您这样做。因此,答案是不用担心它们。use应该在
\uuu destruct()
方法
公共函数{$this->g中添加这一点