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

时间:2013-12-02 22:19:21

标签: php mysqli

我有这段代码,但是当我尝试使用它时,它会给我一个错误,上面写着“致命错误:不能使用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

?>

1 个答案:

答案 0 :(得分:1)

构造函数中参数的顺序是错误的。订单应为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-&gt; 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();

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