sqlsrv_query 没有 return 执行检查数据功能后的任何结果

The sqlsrv_query does not return any result after the checking data function is perform

我的公司项目任务是防止重复输入用户注册数据。我希望防止它们重复的数据是电子邮件(用户不能使用相同的电子邮件注册应用程序)。检查过程涉及两个页面(signup.php和insert.php)。 Signup.php是用户在所有6个页面上输入信息以注册为公司用户的地方。 Insert.php 是将数据插入 sql 服务器的地方,我已经实现了在将数据插入 sql 服务器之前进行检查的代码。

    //email validation
    $emailvalid="SELECT Email FROM EcomLogin WHERE Email  = '$_POST[email]'";
    $stmt3=sqlsrv_query($conn,$emailvalid);
    if($stmt3){
        header("location:signup.php?status=error&message=Error when register with email!");
 exit();
        die(print_r(sqlsrv_errors(), true));
    }

同时在signup.php(注册表)中。在表格顶部,我包含一个 php 代码,如果第一页信息与数据库记录重复,该代码会阻止网站将用户定向到第二个注册页面,在这种情况下是电子邮件。

<?php 
if(isset($_GET['status']) && $_GET['status'] == 'error'){
echo '<script>toastr.error("Email has already been registered!");history.replaceState(null, "", location.href.split("&")[0]);</script>';}
?>

在 head 部分,我还包含了用于 toast 功能的脚本

 <script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js" integrity="sha512-VEd+nq25CkR676O+pLBnDW09R7VQX9Mdiij052gVCp5yVH3jGtH70Ho/UUv4mJDsEdTvqRCFZg0NKGiojGnUCw==" crossorigin="anonymous"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.css" integrity="sha512-3pIirOrwegjM6erE5gPSwkUzO+3cTjpnV9lexlNZqvupR64iZBnOOTiiLPb9M36zpMScbmUNIcHUqKD47M719g==" crossorigin="anonymous" />
    <script src="https://cdn.jsdelivr.net/npm/underscore@1.13.1/underscore-umd-min.js"></script>

在我输入相同的电子邮件地址进行注册后,它会将我带到注册页面的第二页,这是不允许这样做的。如果在第一页上使用重复的电子邮件并将它们阻止到注册页面的第二页,它预计会在第一页上显示一条 toastr 消息。

我的代码是否有任何错误,或者我缺少任何类型的代码来执行 php 文件中的阻止功能?如果编码正确,我是否需要创建另一个功能来防止网站将用户定向到第二页? signup.php 将查看另一个首先验证输入字段的 js 文件,然后仅执行 insert.php.

请记住

 $stmt3=sqlsrv_query($conn,$emailvalid);
    if($stmt3){

可能 return TRUE 即使没有这样的电子邮件,因为 sql 查询是合法的 但不会产生结果或错误。

您可以像这里一样统计电子邮件:

$emailvalid="SELECT count(Email) as found FROM EcomLogin WHERE Email  = '$_POST[email]'";

取记录看found

的值

作为防止重复电子邮件的最后一道防线,您可以在电子邮件上方创建一个 UNIQUE INDEX。有了这个,数据库本身就拒绝重复

您的代码至少存在以下两个问题:

  • 您需要了解 sqlsrv_query() returns 究竟是什么。如documentation中解释的那样,结果是语句资源,或者如果语句无法创建and/or执行,则返回false。因此,检查 if($stmt3) {...} 意味着该语句已正确执行,而不是有包含指定电子邮件的行。
  • 始终使用参数化语句来防止可能的 SQL 注入问题。

如果我对你的问题理解正确,并且你想检查电子邮件是否已经存在,以下方法是可能的解决方案:

  • 使用您当前的语句并使用 sqlsrv_has_rows().
  • 检查结果集是否包含一行或多行
  • 更改语句以获取指定电子邮件的行数。

PHP:

<?
...
$sql    = "SELECT Email FROM EcomLogin WHERE Email = ?";
$params = array($_POST[email]);
$stmt   = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
    header("location:signup.php?status=error&message=Error when register with email!");
    die(print_r(sqlsrv_errors(), true));
}   
if (sqlsrv_has_rows($stmt)) {
    header("location:signup.php?status=error&message=Error when register with email!");
    die(print_r(sqlsrv_errors(), true));
}
...

...
$sql    = "SELECT COUNT(*) AS EmailCount FROM EcomLogin WHERE Email = ?";
$params = array($_POST[email]);
$stmt   = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
    header("location:signup.php?status=error&message=Error when register with email!");
    die(print_r(sqlsrv_errors(), true));
}   
$count = 0;
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)){
    $count = $row["EmailCount"];
}
if ($count >= 1) {
    header("location:signup.php?status=error&message=Error when register with email!");
    die(print_r(sqlsrv_errors(), true));
}
...
?>