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> </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代码有一些不同的问题:
- 您不应该在循环中连接/断开MySQL。这是不必要的开销。相反,在循环之前连接,然后断开连接
- 在查询中使用任何用户输入之前,您需要对其进行消毒。您的代码容易受到SQL注入的攻击
- 您还应该将
header('Location:medical_question.php');
行移到循环之外,并将其更改为die(header('Location:medical_question.php'));
,以阻止脚本的其余部分执行(假设这是您想要的) -
您需要修复查询中的单引号:
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脚本的连接。
这就是发生的事件的过程:
- PHP脚本发送HTTP头,根据延迟的不同,浏览器可能需要一些时间才能接收到它
- 浏览器解释头并重定向到您指定的位置,这也会向当前执行的PHP脚本发送一条断开连接消息
- 同样,根据延迟,服务器可能需要一些时间才能从浏览器接收到断开连接消息
在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之前。
-
字符串在sql查询中用'$string'(撇号)标记
$query="插入许可证(EID,PTYPE)值('$user','$cat')";
-
您可以通过正确的连接只初始化一个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();
这只是一个简单的例子。