是否有必要在准备好的语句中预定义变量?

Is it necessary to pre-defined variables in prepared statement?

我有以下准备好的语句:

            $stmt = $conn->prepare("SELECT * FROM `users` WHERE user LIKE ? ");
            $stmt->bind_param("s", $filtered_form['user']);
            $stmt->execute();
            $stmt->store_result();
            if ($stmt->num_rows > 0) {
               $stmt->bind_result($id, $user, $pass, $first, $last, $type, $email);
               $stmt->fetch();
               $stmt->close();
            }
            if ($pass === $filtered_form['pass']) {
               $_SESSION['id'] = $id;
               $_SESSION['user'] = $user;
               $_SESSION['first'] = $first;
               $_SESSION['last'] = $last;
               $_SESSION['email'] = $email;
               $_SESSION['type'] = $type;
               header("Location:index.php");
               exit;
            } else {
               return "Incorrect password";
            }

但是Visual Studio说有一个问题是变量$id, $user, $pass, $first, $last, $type, $email没有定义。我添加了这样的变量:

            $stmt = $conn->prepare("SELECT * FROM `users` WHERE user LIKE ? ");
            $stmt->bind_param("s", $filtered_form['user']);
            $stmt->execute();
            $stmt->store_result();
            if ($stmt->num_rows > 0) {
               $id  = "";
               $user = "";
               $pass = "";
               $first = "";
               $last = "";
               $type = "";
               $email = "";
               $stmt->bind_result($id, $user, $pass, $first, $last, $type, $email);
               $stmt->fetch();
               $stmt->close();
            }
            if ($pass === $filtered_form['pass']) {
               $_SESSION['id'] = $id;
               $_SESSION['user'] = $user;
               $_SESSION['first'] = $first;
               $_SESSION['last'] = $last;
               $_SESSION['email'] = $email;
               $_SESSION['type'] = $type;
               header("Location:index.php");
               exit;
            } else {
               return "Incorrect password";
            }

问题就迎刃而解了。查看 PHP 文档后,我找不到必须首先定义变量的示例,但 visual studio 仍然显示为错误。知道这是为什么吗?

不,当变量通过引用传递时,没有必要,这里就是这种情况。所以错的是Visual Studio

不过,你这里用的是过时的技术,可以一次性去掉这些误报,减少代码量:

        $stmt = $conn->prepare("SELECT * FROM `users` WHERE user = ? ");
        $stmt->bind_param("s", $filtered_form['user']);
        $stmt->execute();
        $row = $stmt->get_result()->fetch_assoc();
        if ($row and password_verify($filtered_form['pass'], $row['pass']) {
           $_SESSION['user'] = $row;
           header("Location:index.php");
           exit;
        } else {
           return "Incorrect password";
        }

如您所见,get_result() 为您提供比 store_result() 更好的 结果 (双关语并非本意),让您可以存储用户信息在单个变量中,因此它不会乱扔 $_SESSION 数组。

并且 num_rows() 被证明是完全无用的(因为它总是发生)。

重要说明:您永远不应以明文形式存储密码。 Alwas shore a hashed password instead.