我编码中的错误,但不知道如何纠正,不知道是否有人能帮忙


Mistake in my coding, but not sure how to correct it, wonder if anyone can give a hand?

Hi我在php中遇到foreach函数的问题。。。我使用该函数将数组的结果输入到数据库中。例如,如果数组(3,5,7),则系统应向数据库中输入3个不同的条目。然而,在我的案例中,它只创建了一个条目,而完全忽略了其他2个条目。我可以知道是否有人能发现我的错误吗?

我已经创建了一个带有复选框的表单,并尝试检索值,并为每个值提供一个单独的数组,例如:

<form name="appoptions" id="applicationoptions" method="post" action="s_apply_now.php">
<table width="100%" class="apptable" border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td><input type="checkbox" name="cat[]" value="1" /> CAT 2PG</td>
    <td><input type="checkbox" name="cat[]" value="2" /> CAT 1OR</td>
    <td><input type="checkbox" name="cat[]" value="3" /> CAT 2TT</td>
  </tr>
  <tr>
    <td><input type="checkbox" name="cat[]" value="4" /> CAT 3PG </td>
    <td><input type="checkbox" name="cat[]" value="5" /> CAT 2OR</td>
    <td><input type="checkbox" name="cat[]" value="6" /> CAT 3TT</td>
  </tr>
  <tr>
    <td><input type="checkbox" name="cat[]" value="7" /> CAT 4PG</td>
    <td><input type="checkbox" name="cat[]" value="8" /> CAT 3OR</td>
    <td>&nbsp;</td>
  </tr>
</table>
</form>

单击确认后,它将进入处理器页面。在我的处理器页面中,我试图提取值,但我意识到它在一个数组中:

<?php
session_start();
include'Connections/database.php';
$conn = dbConnect ();
    if (! $conn)
    die("Couldn't connect to MySQL");
    $user = $_SESSION['eid'];
    $query = "select MED  from emp where EID = '$user'";
    $result = mysql_query($query, $conn);
    $row = mysql_fetch_assoc($result);
$med = $row['MED']; 
$user =$_SESSION['eid'];
$class=$_POST['class'];
$cat_arr=$_POST['cat'];

$i = 0; /* for illustrative purposes only */
foreach ($cat_arr as $cat) 
{
    if ($med=='no')
    {
        if (! $conn)
        die("Couldn't connect to My SQL");
        $query = "insert into permit (EID, PTYPE, STATUS) values ('$user,$cat, 'medical')";
        $result = mysql_query($query,$conn);
        header ('Location:medical_question.php');
        $i++;
    }
    else
    {
        if (! $conn)
        die("Couldn't connect to My SQL");
        $query = "insert into permit (EID, PTYPE) values ('$user,$cat)";
        $result = mysql_query($query,$conn);
        $i++;
    }
 }
dbDisconnect($conn);
 ?>

我不太确定每一个是否都是错误,但我认为它就在那里。。。

提前谢谢。

我发现您的PHP代码有一些不同的问题:

  1. 您不应该在循环中连接/断开MySQL。这是不必要的开销。相反,在循环之前连接,然后断开连接
  2. 在查询中使用任何用户输入之前,您需要对其进行消毒。您的代码容易受到SQL注入的攻击
  3. 您还应该将header('Location:medical_question.php');行移到循环之外,并将其更改为die(header('Location:medical_question.php'));,以阻止脚本的其余部分执行(假设这是您想要的)
  4. 您需要修复查询中的单引号:

    insert into permit (EID, PTYPE, STATUS) values ('$user,$cat, 'medical')

    应该是:

    insert into permit (EID, PTYPE, STATUS) values ('$user', '$cat', 'medical')

    其他查询也是如此。

最后,你的脚本看起来会更像这样:

$conn = dbConnect();
if (!$conn)
    die("Couldn't connect to MySQL");
$user = mysql_real_escape_string($_SESSION['eid']);
$class = $_POST['class'];
$cat_arr = $_POST['cat'];
foreach ($cat_arr as $cat) 
{
    $cat = mysql_real_escape_string($cat);
    if ($med == 'no')
        $query = "INSERT INTO permit (EID, PTYPE, STATUS) VALUES ('{$user}', '{$cat}', 'medical')";
    else
        $query = "INSERT INTO permit (EID, PTYPE) VALUES ('{$user}', '{$cat}')";
    mysql_query($query);
}
dbDisconnect($conn);
if ($med == 'no')
    $nextPage = "medical_question.php";
else
    $nextPage = "next_page.php";
die(header("Location:{$nextPage}"));

SQL注入示例:

假设您的查询如下:

$user = $_GET["user"];
$cat = $_GET["cat"];
$query = "insert into permit (EID, PTYPE, STATUS) values ('$user', '$cat', 'medical')";

如果我为user:传递这样的值,您的查询会是什么样子

`'); DROP TABLE permit; /*`

这会把你的查询变成这样:

insert into permit (EID, PTYPE, STATUS) values (''); DROP TABLE permit; /*', 'cat', 'medical')

这绝对不是你想要的。当您使用mysql_real_escape_string对输入进行清理时,它将转义单引号字符,查询将失败,或者整个字符串将被插入而不是执行。


更新:

如果您确切地知道函数的作用,那么将header移出循环的原因将更容易理解:

当您调用PHP header函数时,您告诉PHP(在服务器端)向浏览器(在客户端)发送一个HTTP头。在header('Location:...')的情况下,您正在发送一个HTTP标头,该标头会导致浏览器重定向到另一个页面并断开与当前PHP脚本的连接。

这就是发生的事件的过程:

  1. PHP脚本发送HTTP头,根据延迟的不同,浏览器可能需要一些时间才能接收到它
  2. 浏览器解释头并重定向到您指定的位置,这也会向当前执行的PHP脚本发送一条断开连接消息
  3. 同样,根据延迟,服务器可能需要一些时间才能从浏览器接收到断开连接消息

在PHP脚本发送标头然后接收断开连接消息之间,脚本仍在执行。在接收到断开连接消息之前,无法判断脚本将执行多少代码,因此您根本不能依赖于此。这就是为什么您应该在发送标头时die

知道这就是PHP header函数的工作方式,您可能希望将其放入循环中的唯一原因是,如果您希望当前脚本根据某些特定条件在循环中间停止执行。像这样:

foreach ($vars as $var)
{
    if ($var == "stop")
        die(header("Location:anotherPage.php"));
    // do something as long as $var != "stop"
}

这将在$var数组中循环,直到它达到值"stop",此时它将向客户端发送重定向标头并停止执行。

与您的示例的不同之处在于(在编辑之前)您的循环包含一个if-else语句,并且在else中的if中,都有标头重定向调用。所以不管怎样,它都会在循环的第一次迭代中发送,这是没有意义的。如果这真的是你想要的,你就不会使用循环了。它只会执行一次,这违背了循环的目的。

很抱歉收到了冗长的回复,但希望您现在能更好地了解代码中到底发生了什么。

它只插入一次,因为在进行第一次插入后,您将重定向到medical_question.php。

将此重定向移动到foreach之外:

header ('Location:medical_question.php');

此外,您还可以将数据库连接移动到foreach之前。

  1. 字符串在sql查询中用'$string'(撇号)标记

    $query="插入许可证(EID,PTYPE)值('$user','$cat')";

  2. 您可以通过正确的连接只初始化一个db对象($db),并在需要的地方使用它:请参阅http://php.net/manuel/en/ref.mysql.php

例如:

    $conn = new mysqli('localhost', 'root', 'pass', 'db');
    if (mysqli_connect_errno()) {
        exit('Connect failed: '. mysqli_connect_error());
    }
    $sql = "INSERT INTO `table` (`id`, `val`) VALUES (1, 'peace'), (2, 'love')";
    if ($conn->query($sql) === TRUE) {
        echo 'Done';
    }
    else {
        echo 'Error: '. $conn->error;
   }
   $conn->close();

这只是一个简单的例子。