2010-07-14 46 views
1

我正在處理我的第一個登錄腳本。我一直在關注一本書中的例子,但這是我陷入困境的地方。我想用戶登錄是一個電子郵件地址,但是當我點擊提交時,我會得到這個錯誤。@(或「at sign」)正在結束我的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」檢查什麼是錯的,我得到了這個:

Nah. [email protected] 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 

所以,我幾乎肯定@符號結束我的查詢提前。我有trim和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

你周圍的電子郵件地址與您的查詢報價?順便說一句:顯示您的查詢可以真正幫助識別問題。 – Veger 2010-07-14 18:57:48

回答

4

字符串常量需要在單引號:

...WHERE email = '[email protected]' AND password = SHA('password') 

mysql_real_escape_string()函數添加反斜槓您的變量的內容中的特殊字符,但它確實 delimite用單引號括起來的。

例如:

$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無畏領導。

+0

感謝您提供豐富的信息,特別是解釋我的問題和寶貴的安全相關鏈接,作爲一名新的PHP用戶,我們深表謝意! – Tarik 2010-07-14 19:41:46

0

電子郵件地址將是一個字符串:你是否在你的SQL查詢中引用它?以同樣的方式 使用引號,你正在使用他們的$登錄密碼

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

或者更好的是,使用綁定變量,如膽紅素Karwin的例子表明

+0

我會將附加代碼添加到原始文章中,但是我將該電子郵件地址傳遞給一個變量。 – Tarik 2010-07-14 18:59:53