Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/248.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 重写包含已准备语句的变量会关闭该语句吗?_Php_Mysqli - Fatal编程技术网

Php 重写包含已准备语句的变量会关闭该语句吗?

Php 重写包含已准备语句的变量会关闭该语句吗?,php,mysqli,Php,Mysqli,有些人建议在我处理完查询结果后,对准备好的语句调用close() 我经常对准备好的语句重用相同的变量名,因此我想知道重写该变量是否会自动调用准备好的语句上的close() 我当前如何操作的示例(示例由SQL组成): 我是否应该调用$stmt->close()在获取用户和获取帖子之间,还是在调用$stmt=$mysqli->prepare(…)覆盖$stmt时完成?大多数情况下都是这样,因为PHP会尝试尽快清理没有引用的对象。这意味着一旦覆盖它,将不再有对旧对象的引用,PHP将清理它。清理mysq

有些人建议在我处理完查询结果后,对准备好的语句调用
close()

我经常对准备好的语句重用相同的变量名,因此我想知道重写该变量是否会自动调用准备好的语句上的
close()

我当前如何操作的示例(示例由SQL组成):


我是否应该调用
$stmt->close()在获取用户和获取帖子之间,还是在调用
$stmt=$mysqli->prepare(…)覆盖
$stmt
时完成

大多数情况下都是这样,因为PHP会尝试尽快清理没有引用的对象。这意味着一旦覆盖它,将不再有对旧对象的引用,PHP将清理它。清理
mysqli\u stmt
对象的一部分涉及关闭语句

但有些人建议明确调用
$stmt->close()
的原因是为了避免如下错误:

mysqli_sql_异常:命令不同步;您现在无法在中运行此命令

当您尚未从MySQL获取所有结果,并且试图通过调用
prepare
query
创建新语句时,就会发生此错误。在获取所有剩余行之前,MySQL不会让您执行任何其他操作。这通常通过
get\u result()
store\u result()
实现。如果您总是获取全部结果,那么您真的不需要太担心语句何时关闭。让PHP为您处理它

最好的做法是避免直接使用mysqli函数。您应该编写一些简单的函数来封装所有mysqli功能,这样您就不必担心这些低级的东西了。示例函数可能如下所示:

function safeQuery(\mysqli $db, string $sql, array $params = []): ?array {
    $stmt = $db->prepare($sql);
    if ($params) {
        $stmt->bind_param(str_repeat("s", count($params)), ...$params);
    }
    $stmt->execute();
    if ($result = $stmt->get_result()) {
        return $result->fetch_all(MYSQLI_BOTH);
    }
    return null;
}

$result = safeQuery($mysqli, 'SELECT * FROM user WHERE id = ?', [$_GET['userid']]);
if ($result) {
    $user = $result[0];
    $posts = safeQuery($mysqli, 'SELECT * FROM posts WHERE user_id = ?', [$user['id']]);

    foreach ($posts as $post) {
    }
}

是的,大多数情况下,因为PHP会尝试尽快清理没有引用的对象。这意味着一旦覆盖它,将不再有对旧对象的引用,PHP将清理它。清理
mysqli\u stmt
对象的一部分涉及关闭语句

但有些人建议明确调用
$stmt->close()
的原因是为了避免如下错误:

mysqli_sql_异常:命令不同步;您现在无法在中运行此命令

当您尚未从MySQL获取所有结果,并且试图通过调用
prepare
query
创建新语句时,就会发生此错误。在获取所有剩余行之前,MySQL不会让您执行任何其他操作。这通常通过
get\u result()
store\u result()
实现。如果您总是获取全部结果,那么您真的不需要太担心语句何时关闭。让PHP为您处理它

最好的做法是避免直接使用mysqli函数。您应该编写一些简单的函数来封装所有mysqli功能,这样您就不必担心这些低级的东西了。示例函数可能如下所示:

function safeQuery(\mysqli $db, string $sql, array $params = []): ?array {
    $stmt = $db->prepare($sql);
    if ($params) {
        $stmt->bind_param(str_repeat("s", count($params)), ...$params);
    }
    $stmt->execute();
    if ($result = $stmt->get_result()) {
        return $result->fetch_all(MYSQLI_BOTH);
    }
    return null;
}

$result = safeQuery($mysqli, 'SELECT * FROM user WHERE id = ?', [$_GET['userid']]);
if ($result) {
    $user = $result[0];
    $posts = safeQuery($mysqli, 'SELECT * FROM posts WHERE user_id = ?', [$user['id']]);

    foreach ($posts as $post) {
    }
}

表示“如果当前语句有挂起或未读的结果,此函数将取消这些结果,以便执行下一个查询”。恐怕它没有其他用途了。因此,如果这不是一个问题(在您的示例中,它似乎不是),那么我认为您不需要为此烦恼。但是不,覆盖变量不会显式调用close()-不能对不再存在的对象调用方法!虽然我建议不要在同一范围内为不同的目的重复使用同一变量名,但作为一种通用的良好实践,这可能会导致调试和维护期间的混乱,如果管理得不仔细,还会出现意外的错误。最好通过每次使用不同的名称来避免风险。这是否回答了你的问题?感谢您的回复@ADyson,我知道我不能对不存在的对象调用
close()
,但我想知道是否有一个析构函数可以在变量被新对象覆盖时为我调用:-)关于重用变量名,当我与
$stmt
变量交互的唯一时间是在同一个小部分中,以获得结果时,我看不出有什么害处。如果我在同一代码中的多个地方使用一个预先准备好的语句,我当然会给它一个更合适的名称。你可以通过查看源代码来检查是否存在这样的东西。。。表示“如果当前语句有挂起或未读的结果,此函数将取消这些结果,以便执行下一个查询”。恐怕它没有其他用途了。因此,如果这不是一个问题(在您的示例中,它似乎不是),那么我认为您不需要为此烦恼。但是不,覆盖变量不会显式调用close()-不能对不再存在的对象调用方法!虽然我建议不要在同一范围内为不同的目的重复使用同一变量名,但作为一种通用的良好实践,这可能会导致调试和维护期间的混乱,如果管理得不仔细,还会出现意外的错误。最好通过每次使用不同的名称来避免风险。这是否回答了你的问题?感谢您的回复@ADyson,我知道我不能对不存在的对象调用
close()
,但我想知道是否有一个析构函数可以在变量被新对象覆盖时为我调用:-)关于重用变量名,当我与
$stmt
变量交互的唯一时间是在同一个小部分中,以获得结果时,我看不出有什么害处。如果我在同一代码中多个地方使用一个预先准备好的语句,我当然会给出它