Tutorial :Warning: Cannot modify header information - headers already sent by [duplicate]



Question:

Please save me. I know that this question has been asked many times, however, I can't seem to find solutions that are relevant to my situation.

The problem: 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

This is the code block with line 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>  

The definition of the h function:

function h($s){      echo(htmlspecialchars($s,ENT_QUOTES));  }  

This is 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();                }        }      }    }   ?>  

EDIT: would it help to know that I'm trying to handle multiple forms on a single page?


Solution:1

Line 47 modifies the response headers:

header('location: /branch/menus.php'); //line 47  

Line 47 cannot be executed because the headers have already been sent, which happened to occur on line 32. All that happened on line 32 was that PHP decided it had enough content in the response to start sending it back to the browser.

Generally, if you want to modify the headers (whatever you're doing on line 47), you need to do it at the very beginning of the file.

This is a good time to learn about the MVC design pattern - it would eliminate the possibility of this issue in the future. In MVC, the Controller executes first, and prepares everything for the View. So, you can modify your headers all you want in the Controller, and they won't be sent until during or after the View is processed.

EDIT: It looks like you are using MVC, but somehow your view is executing before the controller has started (or perhaps finished)... that shouldn't happen! Unfortunately, the code you've posted doesn't illustrate how either the controller or view are being accessed... but they're being accessed out of order.

As TRiG point out in the comments below, you probably want to insert an exit() statement after line 47 as follows:

header('location: /branch/menus.php'); //line 47  exit();  

This will cause the server to immediately send the Location redirect to the browser, and the request/response cycle is complete. All your header('Location: ...'); calls should be immediately followed by exit();. This doesn't fix the issue at hand, but it is very important.


Solution:2

switch on output buffering, locate php.ini and look for / uncomment / change / add the following line:

output_buffering = On  

edit: and include a line saying ob_start(); in some initial include, like some common init.php or database.php
edit^2: the ob_start is not needed (anymore?); this works, save as test.php and request. Seeing is believing.

Output has started  <?php      header("Content-Type: text/plain");  ?>  

The point is that in HTTP the response of the server consists of 2 parts: the headers and the body.

The headers contain information about the content, the connection etc, like what type of content, e.g.

Content-Type: text/html  or  Content-Type: image/jpeg  

indicating it's html or jpg. Without it, the browser wouldn't be sure what to do with the content. Of course once PHP has to start outputting the body part of the response, there's no way to change the header. So you can either do anything header-related first before emitting any byte of the body, or you could instruct php to hold it's breath and emit the body only when the script is done, or when you say so. And that's what they call output buffering.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »