PHP登录给了我一个致命的错误


PHP login gives me a fatal error?

我有这段代码,但当我尝试使用它时,它会给我一个错误,上面写着"致命错误:无法将mysqli_stmt类型的对象用作数组"。我正试图找到任何试图登录的人的电子邮件附带的用户名。

            <?php if($_SERVER['REQUEST_METHOD'] == 'POST') 
    {
        session_start();
        $sql = new mysqli('hostname', 'dbname', 'username', 'password');
        $email = $_POST['email'];
        $password = $_POST['password1'];
        if(empty($email))
        {
            echo "<p>Email cannot be empty.</p>";
        }
        else if(empty($password))
        {
            echo "<p>Password cannot be empty.</p>";
        }
        else
        {
            $hashinserted = hash('sha512', $password);
            $db = $sql->prepare("SELECT Email, Password, Username FROM Users WHERE Email = ? AND Password = ? ");
            $db->bind_param('ss', $email, $hashinserted);
            $db->execute();
            $db->bind_result($email, $username, $hashinserted);
            $db->store_result();
            if($db->num_rows == 1)  //To check if the row exists
            {
                    $data = $db->fetch_assoc();
                    $username = $data["Username"];
                    $_SESSION['username'] = $username;
                    $_SESSION['loggedin'] = true;
                    $_SESSION['email'] = $email;
                    header('Location:index.php');
                    exit();
            } //check for results
            else
            {
                echo "Whoops! You entered incorrect log in credentials. Try again.";
            } //end incorrect information else
            $db->close();
            $sql->close();
        } //end login else
    } //end server if
?>

构造函数中参数的顺序错误。顺序应为hostuserpassworddatabase

$sql = new mysqli('hostname', 'dbname', 'username', 'password'); -- WRONG
$sql = new mysqli('hostname', 'username', 'password', 'dbname'); -- RIGHT

Prepare()和execute()在出现错误时返回false。您应该始终为此检查返回值。例如:

$db = $sql->prepare("SELECT Email, Password, Username FROM Users 
    WHERE Email = ? AND Password = ? ");
if ($db === false) {
    trigger_error($sql->error, E_USER_ERROR);
}

对于获取行,您混淆了两种不同的获取方式。您使用bind_result(),但随后尝试获取一行数据作为关联数组。使用一种或另一种获取结果的方法。

一种方法是绑定结果,然后调用fetch():

$db->bind_result($email, $username, $hashinserted);
$db->store_result();
...
$db->fetch();
// now $email, $username, $hashinserted have values from the row

另一种方法是调用get_result(),它返回一个mysqli_result资源。然后对该结果资源调用fetch_assoc()以获得一行。

如果调用get_result(),则不能调用store_result)。因为不能调用store_result(),所以不能使用$db->num_rows。如果没有要检索的行,您只需要查看fetch_assoc()是否返回null

$result = $db->get_result();
if (($data = $result->fetch_assoc()) === null) {
    echo "Whoops! You entered incorrect log in credentials. Try again.";
}

我最后的评论是关于变量命名的。当然,变量命名没有硬性规定,但通常根据以下内容命名:

$db = new mysqli(...); // or $mysqli or $link are also common
$sql = "SELECT ...";
$stmt = $db->prepare($sql);
$result = $stmt->get_result();
$row = $result->fetch_assoc();

混淆这些变量名会降低代码对其他人的可读性。