6

From what I have studied, headers cannot be changed after there is an output from a script. Why is it then that in this code sample that I wrote, the script has several outputs before it creates a new header, and yet everything works fine?

<?php
$name = "tommy" ;
?>

<?php 
headers_sent($filename, $linenum) ;
header("name: $name") ;
echo "tommy <br>" ;
echo "Headers  sent in $filename on line $linenum" ;
?>

In addition the output says that the headers were sent in line 0... how is that possible if I added a header afterwards?

7
  • Read output as "Anything that would be read on the html file (when you view the source code)" Commented Apr 4, 2014 at 14:53
  • I received a warning running your script. Maybe your warnings are muted. codepad.org/IGsadvon Commented Apr 4, 2014 at 14:57
  • Is that your actual code? Because it shouldn't work because of the newline on line 4. If you gave this as example, and the php close and open tags aren't there, that's a different story Commented Apr 4, 2014 at 14:59
  • this is the code that I tried intentionally to get an error that headers were already sent. why does it say that they were sent in line 0? Commented Apr 4, 2014 at 15:06
  • and I used the header function after there is an output and the header was added to the respond headers. how? the documentation says that the header function cant be called after an output Commented Apr 4, 2014 at 15:08

6 Answers 6

4
+50

Check if you have Output Buffering set to On in your php.ini. It might also be On by default on some PHP versions, according to this comment on php.net: http://www.php.net/manual/en/ref.outcontrol.php#69059

If that's the case, that's probably why your script executes fine with no errors, even though there is "output" before headers are sent.

EDIT: If you don't have access to the php.ini file itself, you can probably check the value of output buffering from your PHP script by calling ini_get('output_buffering');.

Sign up to request clarification or add additional context in comments.

2 Comments

thank you! I checked and the default value of the output buffer in my php.ini is to send the data after 4096 bytes. do you know what happends if the output buffer exceeds this number? will every additional output not go the buffer? or will the buffer be flushed to the php stream, and the additional data will go to the buffer?
Hmm, I'm not sure to be honest. I think the buffer is emptied every 4096 bytes or at the end of execution, whichever comes first, but I couldn't find any official docs to support this. I could be looking at the wrong place. All in all, seems like a lot of things may implement their own buffering, so you can't always guarantee that your content will reach the client (browser) after X bytes. pa1.php.net/flush#54841 This comment here and it's related code suggest buffering works the way I described it above, though again it's in no way official.
2

If I understood your question correctly then I ask you to look at the value of output_buffering directive in PHP.ini. The default value is 0 but the PHP installers often set it to 4096 (copying from php.ini-development or php.ini-production). This should be the case in your example i.e. the buffering is On.

Secondly, your code example has a flaw; it does not check the value returned by the headers_sent function:

bool headers_sent ([ string &$file [, int &$line ]] )

Check the returned value first; consider the file and line parameters valid if the returned value is true:

<?php
$name = "tommy";
?>

<?php
$sent = headers_sent($filename, $linenum);
header("name: $name");
echo "tommy <br>";
if ($sent) {
    echo "Headers sent in $filename on line $linenum";
} else {
    echo "Headers not sent";
}
?>

Output:

tommy
Headers not sent

In summary:

  1. Your code does not fail because output buffering is on.
  2. Your assumption that your the headers were sent is wrong.

Note: if the output_buffering is set to 4096 then this works:

<?php
echo str_repeat(" ", 4095);
header("X-Foo: Bar");
echo ".";

But this fails with headers already sent error:

<?php
echo str_repeat(" ", 4096);
header("X-Foo: Bar");
echo ".";

Comments

1

Output means, in this case, sending information to the client. Could be an echo, print_r or another form of outputting info in the screen.

There are more ways of outputting data, for example: setting a cookie will also send output. You can't set a cookie and proceed with header changes.

The error in your code: On line 3 you close php ?> and open it on line 5 <?php. Line 4 is output, a \n (newline-character). This will throw an error.
If you do not see that error, your error levels are probaly wrong. You can do an echo above your header, if you still get no errors, it's error_reporting.

7 Comments

He outputted whitespace.
Hm, didn't notice that, be said it works fine, even with this error. Maybe the code is wrong, maybe he doesn't have that open/close
He is missing something. That same script threw a warning for me.
why does the header_sent function says that the headers were sent in line 0?
Could be your file is like this: " <?php" <- space for the open tag. Thats a sneaky one
|
0

use ob_start(); at first line of your php file

1 Comment

They were wondering why they could send HTTP headers after outputting text. This was due to PHP's 4KB of output buffering. They did not want to buffer the output, they wanted to know why text output wasn't preventing setting of HTTP headers.
-1
// -----------------------
ob_start();
// -----------------------

/* Code here */

// -----------------------
$output = ob_get_clean();

if(ob_get_level() > 0)
    ob_end_clean();

echo $output;
// -----------------------

2 Comments

that is not my question. did you suggested a mechanism so that no output will be sent before changing a header? my question is how in my code I can add a header after a outputted before, and it works good
1- you cannot send headers after any output . 2- you just need to control the output buffer and this action done by the way i posted with , -> start an output block -> do anything here -> dispatch/send the output buffer this is the mechanism i use in any application
-2

Make sure you have no blank symbols before sending header in your case

<?php
$name = "tommy" ;

?>




<?php 


headers_sent($filename, $linenum) ;
header("name: $name") ;
echo "tommy <br>" ;

echo "Headers  sent in $filename on line $linenum" ;
?>

between ?> and <?php you have 5 new line characters which may cause the problem, if you include this file into another make sure main file has no any characters output above your header commands.

2 Comments

can anyone explain me what is wrong with my answer?
The OP wanted to understand why HTTP headers could successfully be set AFTER there was text output in their PHP code. The reason for this is PHP's 4KB of output buffering, so no text had yet been sent to the browser when the HTTP headers were set.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.