在使用php插入sql之前检查记录

Posted

技术标签:

【中文标题】在使用php插入sql之前检查记录【英文标题】:checking record before inserting in sql using php 【发布时间】:2012-09-10 05:55:37 【问题描述】:

我正在使用 INSERT 语句添加记录。现在我想检查电子邮件是否已经注册或是否已经存在于记录中。如果它已经存在,则给出一个错误,否则插入一条新记录。这就是我的做法...但是选择查询是没有运行...并且仍然在不检查的情况下添加记录。请检查我的代码并提出解决方案。谢谢 :) 这是我的代码

 manage-users.php
<?php include("../includes/config.php"); ?>
<?php
if ($_SESSION["isadmin"])

?>
<!DOCTYPE html>
<html>
<head>
<?php include("includes/pre-header.php");?>


<title>Admdin Home</title>
</head>
<body>
<div class="container">
<?php include("includes/header.php"); ?>
<?php include("includes/nav.php"); ?>
<div id="maincontent">

<div class="span-24 last">
<div id="breadcrumbs">
    <a href="">Home</a> >
    <a href="">Manage Users</a> >
    Add New
</div>
</div>
<?php include("includes/manage-users-aside.php"); ?>
<div class="span-18 last">
<h2 class="alt">Add New</h2>
<?php
if (isset($_GET["status"]))

if($_GET["status"]==1)

?>
<div class="success">
<?php
echo("<strong>User Has Been Added Successfully!</strong>");
?>
</div>
<?php

 if($_GET["status"]==2)

?>
<div class="success">
<?php
 echo("<strong>User Has Been Edited Successfully!</strong>");
?>
</div>
<?php

 
 if($_GET["status"]==3)

echo ("<strong>This Account Already Exixts!. Please add a New One!</strong>");

?>
<form method="post" id="form" action="manage-users-action.php">
<label for="email">Email/Username:</label><input id="email" type="text" name="email" value="" class="text" /><br /><br />
<label for="password">Password:</label><input id="password" type="password" name="password"  value="" class="text" /><br /><br />
<label for="firstname">First Name:</label><input id="firstname" type="text" name="firstname" value="" class="text" /><br /><br />
<label for="lastname">Last Name:</label><input id="lastname" type="text" name="lastname"    value="" class="text" /><br /><br />
<label>Type:</label><br />
<input type="radio" name="type" value="S" />Student <br /> <br />
<input type="radio" name="type" value="T" />Teacher<br /><br />
<input type="submit" name="submit"  value="Submit" class="button" />
</form>
</div>
</div>

<?php include("includes/footer.php"); ?>
</div>
</body>

</html>
<?php

else

    header("Location: ".$fullpath."login/unauthorized.php");

 
?>

这是manage-users-action.php

<?php include("../includes/config.php");?>
<?php
$fname=$_POST['firstname'];
$lname=$_POST['lastname'];
$type=$_POST['type'];
$email=$_POST['email'];
$pwd=$_POST['password'];
$recoverykey=md5(time());
$encpwd=md5($pwd);
$con=mysql_connect($dbserver,$dbusername,$dbpassword);
if (!$con)  die('Could not connect: ' . mysql_error()); 
mysql_select_db($dbname, $con);

$result= mysql_query("SELECT FROM accounts WHERE (email='".$email."')");
if(!$result)
$sql=("INSERT INTO accounts VALUES   (NULL,'".$email."','".$encpwd."','".$fname."','".$lname."','".$type."','".$recoverykey."')"    );

else

 header("Location: manage-uesrs.php?status=3");

if (!mysql_query($sql,$con))

die('Error: ' . mysql_error());

else
    
        header("Location:manage-users.php?status=1");
    

mysql_close($con);
?>

【问题讨论】:

为什么要先检查?如果数据库对该列有唯一约束,尝试插入,如果返回重复索引错误,在代码中处理。您节省了前往数据库的行程。 @xQBert,比一个答案,我会投票给它。 @AlainCollins 我会,但它没有解决具体问题。这就是为什么我把它作为评论留下。答案应针对具体问题。我绕道而行;但我不认为这是值得回答的,除非问题更改为“插入记录时处理检查重复项的最佳方法是什么”(我最好的方法是让存储过程完成工作并将内联 SQL 删除为它为 SQL 注入打开了大门。)我只是想让作者考虑替代方案。 您检查了他的代码并按照他的要求提供了解决方案。这是对我的回答,该死的纳粹。好的,那我就点赞你的评论。叹息。 @Riu,既然您认为是“未运行”的是 SELECT,您是否手动运行了 exact SELECT 语句? 【参考方案1】:

代替

if (!$result) 

试试

if ( mysql_num_rows($result) == 0 )

您的查询总是会返回一个结果 - 即使数据库中没有记录 - 这就是为什么您的条件从未奏效。

【讨论】:

【参考方案2】:

您实际上在流程中有几个错误。 Zolthan 是对的,但是您仍然会在数据库中得到两个条目,因为您的代码将在“标题”之后继续执行。在“标头位置”调用之后总是exit();

您还需要验证/确保您的数据安全(否则 $retval 将是错误的,并且如果您完全按照 Zoltan 操作,它会出错。)

解决问题:

// Validate you have an valid email
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) 
     header("Location: manage-uesrs.php?status=ErrorInSQL");    // Note: location should take a full URL. This works in all browsers I know of, but is not strictly correct.
     exit();  // Critical - otherwise you script will continue to run.


// Than sanatize your data. Use PDO or mysql; for for now I'll use your code
$email = mysql_real_escape_string($email);
// Repeat for the other fields

$result= mysql_query("SELECT FROM accounts WHERE (email='".$email."')"); 
if (!$result)  
     header("Location: manage-uesrs.php?status=ErrorInSQL");    // Note: location should take a full URL. This works in all browsers I know of, but is not strictly correct.
     exit();  // Critical - otherwise you script will continue to run.
 else (mysql_num_rows($result) > 0 )  
     header("Location: manage-uesrs.php?status=NotUniqueURL");
     exit();  // Critical - again.


// As we're here, we can now do thq SQL as you have
// Remmber mysql_real_escape_string on all variables (or use PDO / mysqli prepared statements)
$sql=("INSERT INTO accounts VALUES   (NULL,'".$email."','".$encpwd."','".$fname."','".$lname."','".$type."','".$recoverykey."')"    ); 
if (mysql_query($sql,$con)) 
    header("Location:manage-users.php?status=1"); 
    exit();   // ;)
 else 
    header("Location: manage-uesrs.php?status=ErrorInSQL");
    exit();   // ;)

但是,正如 xQbert 所建议的,您最好的方法是在一个查询中。

在“电子邮件”字段的数据库中创建一个“唯一”索引。

// Validate you have an valid email
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) 
     header("Location: manage-uesrs.php?status=ErrorInSQL");    // Note: location should take a full URL. This works in all browsers I know of, but is not strictly correct.
     exit();  // Critical - otherwise you script will continue to run.


// Than sanatize your data. Use PDO or mysql; for for now I'll use your code
$email = mysql_real_escape_string($email);
// Repeat for the other fields

// Dive traight into the SQL
// Remmber mysql_real_escape_string on all variables (or use PDO / mysqli prepared statements)
$sql=("INSERT INTO accounts VALUES   (NULL,'".$email."','".$encpwd."','".$fname."','".$lname."','".$type."','".$recoverykey."')"    ); 
if (mysql_query($sql,$con)) 
    header("Location:manage-users.php?status=1"); 
    exit();   // ;)
 else 
    // This could error because it is in use, or you have error in your sql. So debug with mysql_error() initially to get your SQL correct, then when you're sure that is right, assume any error is duplicate e-mail. You could alsocheck with with mysql error codes to be extra safe.  
    header("Location: manage-uesrs.php?status=AlreadyInUse");
    exit();   // ;)

【讨论】:

以上是关于在使用php插入sql之前检查记录的主要内容,如果未能解决你的问题,请参考以下文章

在插入之前检查现有记录

实体框架:在插入新记录之前检查记录是不是存在

PL/SQL 触发器在插入语句之前检查值

laravel 在插入之前检查记录是不是存在,这是一种有效的方法

使用php脚本检查一个表中的重复记录并重复记录插入到另一个表中

在插入新记录之前触发检查部门的平均工资