2016-07-04 89 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之一。 –