2016-07-04 82 views
1

我在php中創建了一個非常簡單的註冊表單,當用戶嘗試註冊時,會彈出一個帶有成功或失敗消息的JavaScript警報。SQL插入後的PHP異常處理

現在我想捕獲sql異常,以顯示用戶名或電子郵件是否已經在數據庫中感染而不是標準的失敗消息。

這是我到目前爲止的代碼:

if(isset($_POST['btn-signup'])) 
{ 
    $uname = mysql_real_escape_string($_POST['uname']); 
    $email = mysql_real_escape_string($_POST['email']); 
    $upass = md5(mysql_real_escape_string($_POST['pass'])); 

    if(mysql_query("INSERT INTO user(username,password,email) VALUES('$uname','$upass','$email')")) 
{ 
?> 
    <script>alert('successfully registered ');</script> 
<?php 
} 
else{ 
?> 
    <script>alert('error while registering you...');</script> 
<?php 
} 
} 
?> 

我如何檢查電子郵件或用戶名在數據庫中已經excists?這兩個變量在數據庫中都是唯一的。

+5

請不要使用'md5()'來輸入密碼,特別是如果它們沒有聲明的話。 –

+3

**警告:**'mysql_ *'API已被棄用並從PHP7.0.0開始刪除。考慮使用['mysqli'](http://php.net/mysqli)或['pdo'](http://php.net/pdo)並綁定您的參數。 –

+0

感謝您的信息,不知道這一點。 –

回答

2

從評論:

我不想2次的查詢,而數據庫可以返回爲我破例。如果該表中有大約1000萬條記錄,我不想在插入新記錄之前檢查它們。

好的,你有一個查詢插入和檢查是唯一的嗎?所以,你要插入一個UNIQUE_INDEX MySQL的列,則可以捕捉這些異常的排序與答案shameless stolen from this answer以下風格this question

在這個答案的情況下,我們假設你正在使用PDO,因爲你應該。請閱讀它。

// Pre-setup the database connection somewhere, usually an include (or a class) 
$link = new PDO("mysql:host=$dbhost;dbname=$dbname",$dbusername,$dbpassword); 
// PDO needs to be set in Exception mode: 
$link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

//Input Processing functions. 
// (entirely optional) 
$uname = MyCleanerFunction($_POST['uname']); 
$email = MyCleanerFunction($_POST['email']); 
//please see note below re:MD5 
//$upass = md5($_POST['pass']); 
$options['cost'] = 12; 
$upass = password_hash($_POST['pass'],PASSWORD_BCRYPT,$options); 

//now reach the code part: 
    try { 
     //PDO query execution goes here: 

     $statement = $link->prepare("INSERT INTO user(username,password,email) VALUES(:uname, :email, :pass)")); 
     $statement->bindValue(":uname", $uname); 
     $statement->bindValue(":email", $email); 
     $statement->bindValue(":pass", $upass); 
     $statement->execute(); 
     //reaching here everything is ok! 
    } 
    catch (\PDOException $e) { 
     if ($e->errorInfo[1] == 1062) { 
      // The INSERT query failed due to a key constraint violation. 
      // THIS means that it failed because the Primary Key 
      // (the email) appears already in the database table. 
     } 
     if($e->errorInfo[1] == 9999){ 
      // possible other IF clauses for other errors in INSERT. 
     } 
    } 

你也應該好好讀了大約catching and outputting PDO errors。以及所有關於MySQL Unique Key Constraints

  • 也很有用的替代觀點,你Should not catch PDO exceptions

  • 同時請注意,MD5是極其微弱哈希存儲密碼和PHP password_hash功能是做它的更喜歡方式。

  • 使用準備好的發言你的MySQL互動,佈局上面是一個粗略的指南,他們怎麼看,是MySQLiPDO非常相似。準備好的陳述去很長的路朝着保護您的數據免受惡意用戶輸入。

+0

請您在回答中提供關於在密碼上使用'md5()'的注意事項。 –

+0

我剛剛做完了@ʰᵈˑ – Martin

+0

如果使用綁定參數,'MyCleanerFunction'不需要存在。 – AD7six

-1

嗯,我可以給你的代碼,但首先你試試這個。

首先你需要在代碼中創建的成功部分的查詢將從表 獲取所有的用戶名,然後使用,如果你有一個條件由用戶來檢查它的數據輸入

該代碼可以像下面這樣植入: 「從用戶名中選擇用戶名username ==='$ username'」; if($ username === input_username){ 會引發錯誤。 }

謝謝。

+0

除了首先使用select語句之外,沒有其他選擇嗎?如果表中有大約1000萬條記錄,我不想在插入另一條記錄之前檢查它們中的每一條。 –

+0

如果電子郵件或用戶名已被刪除,數據庫未插入新行,那麼是否有可能發現此異常? –

+0

那麼select語句會出現在你已經成功警告的地方 –

-2
$con=mysqli_connect("localhost","root","","my_db"); 
$check="SELECT COUNT(*) FROM persons WHERE Email = '$_POST[eMailTxt]'"; 
if (mysqli_query($con,$check)>=1) 
{ 
    echo "User Already in Exists<br/>"; 
} 
else 
{ 
    $newUser="INSERT INTO persons(Email,FirstName,LastName,PassWord) values('$_POST[eMailTxt]','$_POST[NameTxt]','$_POST[LnameTxt]','$_POST[passWordTxt]')"; 
    if (mysqli_query($con,$newUser)) 
    { 
     echo "You are now registered<br/>"; 
    } 
    else 
    { 
     echo "Error adding user in database<br/>"; 
    } 
} 
+1

不提供代碼解答。解釋你的答案。 –

+2

另外,恭喜。**您的答案可以執行SQL注入**。使用'mysqli'本身並不安全。 **綁定你的參數**。 –

+0

以及您聲明爲百萬用戶檢查用戶名將是一件繁忙的工作,所以您可以檢查結果數量。計數同時做兩個工作一個用於搜索和其他mysqli_num_rows之一。 –