@(或“at sign”)提前结束我的MySQL查询,导致错误

时间:2010-07-14 18:53:07

标签: php mysql

我正在处理我的第一个登录脚本。我一直在关注书中的例子,但这是我被困的地方。我希望用户登录成为电子邮件地址,但是当我点击提交时,我会收到此错误。

Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in C:\wamp\www\mysite\index.php on line 19

脚本在书中起作用,没有拼写错误,而且我发现如果原始查询失败会给出错误,所以我决定插入一个“mysqli_error”来检查错误,我得到了这个: / p>

Nah. admin@mysite.comYou have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@mysite.com AND password = SHA('password')' at line 1

所以,我几乎肯定@符号提前结束我的查询。我有修剪和mysql_real_escape_string作为清理字符串的方法,但除此之外我什么都没有。我已经谷歌搜索了一段时间,我找不到或弄清楚如何为@(“at sign”)或某种类型的工作做出例外。

我不希望这个问题太长或太复杂,但如果需要,我可以提供更多代码。

谢谢!

修改:以下是缩小解决方案范围的完整代码。

if (isset($_POST['submit'])) {

    $loginEmail = mysqli_real_escape_string($dbc, trim($_POST['loginEmail']));
    $loginPassword = mysqli_real_escape_string($dbc, trim($_POST['loginPassword']));        

    $query = "SELECT user_id, username FROM user_db WHERE email = $loginEmail AND password = SHA('$loginPassword')";
    $loginData = mysqli_query($dbc, $query);

    if (mysqli_num_rows($loginData) == 1) {
        echo 'You win!';
    }

    else {
        $error = mysqli_error($dbc);
        echo 'Nah. ' . $loginEmail . $error;
    }
}

2 个答案:

答案 0 :(得分:4)

字符串文字必须是单引号:

...WHERE email = 'accountname@example.com' AND password = SHA('password')

mysql_real_escape_string()函数会在变量内容中的特殊字符处添加反斜杠,但它用单引号分隔字符串。

例如:

$loginEmail = "O'Reilly";
$loginEmail = mysql_real_escape_string($loginEmail);

现在$ loginEmail的内容是:

O\'Reilly

'O\'Reilly'

所以你需要自己在SQL表达式中添加引号:

$query = "SELECT user_id, username FROM user_db 
          WHERE email = '$loginEmail' AND password = SHA('$loginPassword')";

我真的建议使用PDO和准备好的查询,而不是将所有细节插入到SQL中。这样,您就不必担心mysql_real_escape_string()或引号或特殊字符。

$pdo = new PDO(...connection arguments...);
$sql = "SELECT * FROM mytable WHERE email = ? AND password = SHA(?)";
$stmt = $pdo->prepare($sql);
$stmt->execute(array($loginEmail, $loginPassword));

请参阅?您不需要在?参数占位符周围使用单引号,您不需要转义作为参数传递的变量,但您不必担心SQL注入。

另见我的演讲SQL Injection Myths and Fallacies

另请阅读无畏领袖的You're Probably Storing Passwords Incorrectly

答案 1 :(得分:0)

电子邮件地址将是一个字符串:您是在SQL查询中引用它吗? 使用引号的方式与将它们用于$ loginPassword

的方式相同
$query = "SELECT user_id, username FROM user_db WHERE email = '$loginEmail' AND password = SHA('$loginPassword')"; 

或更好的是,使用绑定变量,如Bil Karwin的示例所示