MySQLi,为什么提取?检查查询的最安全方法


MySQLi, why fetch? Safest way to check query?

对于登录系统,我想检查用户名和密码是否正确,这是代码(没有检查错误等):

$db = @new MySQLi('localhost', 'user', 'pw', 'db');
$sql = 'SELECT
            id
        FROM
            members
        WHERE
            username = ? AND
            password = ?';
$stmt = $db->prepare($sql);
$stmt->bind_param('ss', $username, $password_hash);
$stmt->execute()
$stmt->bind_result($UserID);

现在我想检查一下是否有结果,在大多数教程中都是这样做的:

if (!$stmt->fetch()) {
    //LOGIN WAS INCORRECT, DO STUFF
} else {
    //LOGIN WAS CORRECT, DO STUFF
}

但为什么呢?它也是这样工作的:

if (isset($UserID)){
    //LOGIN WAS CORRECT, DO STUFF
} else {
    //LOGIN WAS INCORRECT, DO STUFF

或:

if ($UserID != 0){
    //LOGIN WAS CORRECT, DO STUFF
} else {
    //LOGIN WAS INCORRECT, DO STUFF

那么,什么是最快、最安全的方法呢?

您既不需要"最快"(因为没有什么是慢的)也不需要"安全的"(因为也没有什么是不安全的)。

你需要的只是一种明智的方式。

$stmt = $db->prepare($sql);
$stmt->bind_param('ss', $username, $password_hash);
$stmt->execute()
$stmt->bind_result($UserID);
$stmt->fetch();

现在您有了$UserID变量来检查并将其保存到会话中。

if ($UserID) {
    $_SESSION['auth'] = $UserID;
}

正如你所看到的,原始的mysqli使用起来非常冗长和丑陋。这就是为什么你不应该使用它,而是使用一些抽象层,比如这个

$db = new safeMysql();
$sql = 'SELECT id FROM members WHERE username = ?s AND password = ?s';
if ($UserID = $db->getOne($sql, $username, $password_hash));
    $_SESSION['auth'] = $UserID;
}