【问题标题】:Why do we close result in Mysqli为什么我们在 Mysqli 中关闭结果
【发布时间】:2012-03-09 06:38:57
【问题描述】:

我们为什么要关闭 $result

    $mysqli = new mysqli("localhost", "root", "root", "test");
    if ($mysqli->connect_errno) {
        echo "Failed to connect to MySQL: " . $mysqli->connect_error;
    }

    if ($result = $mysqli->query("Select * from user")) {
        while ($row = $result->fetch_object())
        {
            //var_dump($row);
        }
        $result->close();
    }   

【问题讨论】:

  • 自从我使用 MySQLi 以来已经很长时间了,但似乎 query() 返回一个布尔值或 mysqli_result 对象。而且似乎 mysqli_result 没有 close() 方法?你是说free()吗?
  • 啊,php.net/manual/en/class.mysqli-result.php 没有列出它,但是 free() 页面列出了 close() 作为别名。答案如下。
  • 您仍然使用 MySQLi 而不是像 PDO 这样的(更)现代的东西,是否有特定的原因?
  • gud 问题,但 mysqli 比 pdo 快

标签: php mysql mysqli


【解决方案1】:

您对连接是否失败的检查由使用该连接的代码来完成。显然这行不通,因为它不是实时连接。确保如果连接失败,则不会到达依赖于它的代码。 (请注意,我没有必要提倡使用 exit 或 die。它们可能会造成相当糟糕的用户体验。它们可能很有用,但理想情况下,您应该输出更好的消息并将丑陋的错误内容留给日志 [除非您'重新测试或者它是一个命令行脚本])。

至于close()(其实是free()的别名):

free() 基本上释放了所有附加到结果的东西。您需要了解检索行有两种(简化,但顺其自然)方式:

缓冲 - 一切都被一口气抢走。换句话说,当你开始循环遍历记录时,它们实际上都已经在内存中了。它们是缓冲的。每次调用 fetch() 时,它们都不会从服务器中拉出,而是从内存中拉出。

非缓冲 - 可能有一个小缓冲区,但基本上每次调用 fetch() 时,PHP 都必须从数据库中拉出一个新行。在循环开始时,它们并不都在内存中。

有趣的注释: num_rows() 可以在缓冲查询上非常有效地调用,因为所有行都已经被拉出(尽管你永远不应该拉出所有的行来计算它们——这就是 COUNT 的用途)。非缓冲查询在提取所有行之前无法执行 num_rows()。这意味着它要么是一个错误,要么本质上会将它变成一个缓冲查询。

无论如何,回到你的实际问题:

free() 释放任何与结果对象相关的东西。在缓冲查询的情况下,这是位于内存中的任何行。在非缓冲查询的情况下,free() 将释放内存中可能存在的任何行,然后取消其余的请求。基本上它的 PHP 告诉 MySQL,“嘿,你知道我请求的所有行吗?改变了我的想法。你可以放弃那个请求。”

至于你是否应该释放结果......好吧,只要变量超出范围*,它无论如何都会发生。但是,显式执行它并没有什么害处,并且在查询可能使用大量内存然后另一个查询可能使用大量内存之后的情况下,您可能希望释放集合以保持低内存使用率.

* 或者当请求结束时。我不记得了。

【讨论】:

  • 您只需要在select 语句上使用->close() 对吗?而不是像insertupdate 这样的其他东西,因为它们不返回任何东西?
  • @AndyLobel 我相信你是对的。我不积极,但由于插入/更新/等没有结果集,所以不应该有任何东西可以释放。
猜你喜欢
  • 1970-01-01
  • 2011-01-25
  • 1970-01-01
  • 2011-05-27
  • 2011-05-31
  • 1970-01-01
  • 2014-06-29
  • 2016-11-05
  • 1970-01-01
相关资源
最近更新 更多