请救救我。我知道这个问题已被多次询问,但是,我似乎无法找到与我的情况相关的解决方案。
问题:Warning: Cannot modify header information - headers already sent by (output started at /.../Sites/st.ambulance/resources/views/login.view.php:32) in /.../Sites/st.ambulance/resources/controllers/tables_.php on line 47
这是第32行的代码块:
<label>Month</label>
<select name="dob_month">
<?php for($i=0,$j=1;$i<sizeof($month);$i++,$j++){ ?>
<option value="<?php h($j) ?>"><?php h($month[$i]) ?></option> //line 32
<?php } ?>
</select>
h函数的定义:
function h($s){
echo(htmlspecialchars($s,ENT_QUOTES));
}
这是tables_.php:
<?php
$error = "";
if(isset($_POST['guest_tables'])){
if(isset($_SESSION['logged_in']) && $_SESSION['logged_in']){
$guest = array();
$volunteer = array();
$guest = isset($_POST['guest']) ? $_POST['guest'] : null;
$volunteer = isset($_POST['volunteer']) ? $_POST['volunteer'] : null;
$seat_array = array($volunteer['seat_no'].$volunteer['table']);
$seat_count = 0;
$table_seat_error = "";
if($form->is_seatOccupied($volunteer['table'],$volunteer['seat_no']) != "")
$table_seat_error .= "Seat (".$volunteer['seat_no'].")
at table (".$volunteer['table'].") is currently occupied";
if($_SESSION['no_guests'] >= 1){
if($guest && $volunteer){
foreach($guest as $gue){
$seat_table = $gue['seat_no'].$gue['table'];
for($h=0;$h<sizeof($seat_array);$h++){
if($seat_table == $seat_array[$h] )
$seat_count = $seat_count + 1;
}
if($form->is_seatOccupied($gue['table'], $gue['seat_no']) != "")
$table_seat_error .= "Seat (".$gue['seat_no'].")
at table (".$gue['table'].") is currently occupied";
$seat_array[] = $seat_table;
}
if($seat_count == 0){
if($table_seat_error == ""){
for($d=0;$d<$_SESSION['no_guests'];$d++){
$_SESSION['guests'][$d]['table'] = $guest[$d]['table'];
$_SESSION['guests'][$d]['seat'] = $guest[$d]['seat_no'];
}
$_SESSION['volunteer']['table'] = $volunteer['table'];
$_SESSION['volunteer']['seat'] = $volunteer['seat_no'];
$form->set_guests($_SESSION['guests']);
$form->set_volunteer($_SESSION['volunteer']);
header('location: /branch/menus.php'); //line 47
exit();
}
else{
$error = $table_seat_error;
}
}
else{
$error = "You have selected the same seat for two or more
people: one person, per seat, per table. Only.";
}
}
}
else{
$_SESSION['volunteer']['table'] = $volunteer['table'];
$_SESSION['volunteer']['seat'] = $volunteer['seat_no'];
if(!$form->is_seatOccupied($_SESSION['volunteer']['table'],
$_SESSION['volunteer']['seat']) != ""){
$form->set_volunteer($_SESSION['volunteer']);
header('location: /branch/menus.php');
exit();
}
}
}
}
?>
编辑:知道我正在尝试在一个页面上处理多个表单会有帮助吗?
答案 0 :(得分:3)
第47行修改响应标题:
header('location: /branch/menus.php'); //line 47
第47行无法执行,因为标题已经发送,这恰好发生在第32行。第32行发生的一切是PHP确定响应中有足够的内容开始将其发送回浏览器。
通常,如果你想修改标题(无论你在第47行做什么),你需要在文件的最开头。
现在是了解MVC design pattern的好时机 - 它将在未来消除此问题的可能性。在MVC中,Controller首先执行,并为View准备一切。因此,您可以在Controller中修改所需的标题,直到处理视图期间或之后才会发送它们。
编辑:看起来你正在使用MVC,但不知何故你的视图在控制器启动(或者可能已完成)之前正在执行......这不应该发生!遗憾的是,您发布的代码并没有说明如何访问控制器或视图......但是它们是无序访问的。
正如TRiG在下面的评论中指出的那样,您可能希望在第47行之后插入exit()
语句,如下所示:
header('location: /branch/menus.php'); //line 47
exit();
这将使服务器立即将位置重定向发送到浏览器,并且请求/响应周期完成。 所有您的header('Location: ...');
来电应紧跟exit();
。这并不能解决手头的问题,但这非常重要。
答案 1 :(得分:0)
打开输出缓冲,找到php.ini并查找/取消注释/更改/添加以下行:
output_buffering = On
编辑并在某些初始包含中添加一行ob_start();
,例如一些常见的init.php或database.php
编辑^ 2:不需要ob_start
(已经?);这工作,保存为test.php和请求。眼见为实。
Output has started
<?php
header("Content-Type: text/plain");
?>
关键是在HTTP中,服务器的响应由两部分组成:标题和正文。
标题包含有关内容,连接等的信息,例如内容的类型,例如
Content-Type: text/html
or
Content-Type: image/jpeg
表示它是html或jpg。没有它,浏览器将无法确定如何处理内容。当然,一旦PHP必须开始输出响应的正文部分,就无法更改标题。因此,您可以在发出正文的任何字节之前先执行任何与标题相关的操作,或者您可以指示php保持它的呼吸并仅在脚本完成时释放正文,或者当您这么说时。这就是他们所说的输出缓冲。