gpt4 book ai didi

PHP:mysqli_stmt->close() 影响 stmt 的早期副本

转载 作者:行者123 更新时间:2023-12-04 09:16:53 24 4
gpt4 key购买 nike

我正在制作一个函数,以便在 sql 查询中更轻松地使用准备好的语句。但是在处理它的过程中,我遇到了一个奇怪的错误。
当您运行第一个 var_dump 下面的代码时的 $response打印 $stmt像我期望的那样变量,但是在关闭 $stmt 之后它给出了很多警告并打印了一个 NULL 填充版本的 $stmt .我只复制 $stmt 为 $response ,所以我没想到 $response关闭时更改 $stmt .
有人可以解释为什么会发生这种情况以及我如何防止它?

function sql_bug() {
global $dbc; // Database connection
$sql = "UPDATE users SET username = 'J0R1AN' WHERE id = 1"; // Test query
if ($stmt = $dbc->prepare($sql)) {
if ($stmt->execute()) {
$response = $stmt->get_result();
if ($response === false) {
// Checks for e.g. UPDATE queries that return bool(false) instead of a mysqli_result,
// and sets $response to $stmt instead, to return more valuable information when using UPDATE
$response = $stmt;
}
var_dump($response); // Prints expected $stmt variable
$stmt->close(); // Somehow changes $response?
var_dump($response); // Prints $stmt variable filled with NULLS
return $response;
}
}
return false;
}

最佳答案

变量赋值不会在 PHP 中创建对象的新副本。要创建副本,您需要使用 clone .简单的例子:

$obj  = (object) ['a'=>42];
$new_obj = $obj;
$obj->a = 100;

var_dump($new_obj);
// outputs
// stdClass Object
// (
// [a] => 100
// )
您已成为多种谬论的受害者。
  • 您不需要close任何事物。 PHP 会为你做的。使用 close只会使很多事情复杂化。
  • 不检查 prepare 的返回值或 execute职能。而是启用 mysqli 错误报告。 How to get the error message in MySQLi?
  • 不要使用全局对象或将它们的使用限制在绝对最小值。
  • 你不需要暴露mysqli_stmtmysqli_result函数之外的对象。执行语句并获取数据后,您可以丢弃它们。

  • 如果我们想正确修复这个函数,我们可以这样做:
    function sql_bug(\mysqli $dbc, string $sql, array $params = []): ?array {
    $stmt = $dbc->prepare($sql);
    if ($params) {
    // bind optional parameters if the query has variable input
    $stmt->bind_param(str_repeat("s", count($params)), ...$params);
    }
    $stmt->execute();
    $response = $stmt->get_result();
    if ($response) {
    // If the query returned results then fetch them into an array and return it
    return $response->fetch_all(MYSQLI_BOTH);
    }
    // return nothing if the query was successfully executed and it didn't produce results
    return null;
    }
    上面的函数是一个泛型函数,可以处理任何带参数和不带参数的SQL语句。如果查询是 INSERT 或 UPDATE 它不会返回任何东西,如果它是 SELECT 它将返回数组中的数据。无需复制或返回内部对象。您正在编写一个函数来从 mysqli 内部进行抽象。

    关于PHP:mysqli_stmt->close() 影响 stmt 的早期副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63178884/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com