4

I noticed that there are two empty lines above the HTML in the source code of my website. It looks like this:

<!-- Two empty lines here, StackOverflow won't let me post empty lines -->

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html>

The HTML is generated using PHP. How can I find out where the output started?

I tried adding <?php header('...'); ?> after <html>, hoping to trigger an error like "Cannot modify header. Output started at line ..." But no error occurred.

hakre
  • 193,403
  • 52
  • 435
  • 836
Linksku
  • 1,449
  • 6
  • 17
  • 22
  • 1
    hmm,could you post the code that generates this?? – Paris Liakos Jul 13 '11 at 21:05
  • do you have a complex include structure? are you guesing witch one is the gilty? all your files have – Saic Siquot Jul 13 '11 at 21:11
  • @Linksku, there is a fundamental problem with your code if you have many blank lines before your expected HTML starts. You should check ALL of your files for blank lines before **AND** after any `` tags, as that causes this issue to crop up. You should also look into output buffering, as described in my answer, if your using header functions after using an print, echo, or non-php formatted HTML output. – Mark Tomlin Jul 13 '11 at 21:27
  • Problem is, I'm using WordPress, and I have 15mb of PHP (including plugins). It's going to take a very long time to go through all of them. The ob_start() answer looks promising, but the answerer misunderstood my question. – Linksku Jul 13 '11 at 21:34
  • @Linksku, indeed. That's a lot of code to go over. I would start by turning off all plugins, and see if there blank lines are still there. If they are it's not the plugins that are causing it. If the blank lines go, then you know the problem is no in the core and you just have to pin point the plugin that is causing the problem, for that it's as simple as turning the plugins on, one by one and finding out if the blank lines reappear. – Mark Tomlin Jul 13 '11 at 21:42

7 Answers7

17

If you want to obtain the filename and line-number where the output started, you can call the headers_sent() function with two optional parameters:

$sent = headers_sent($file, $line);

Those two variables $file and $line will contain the information you're looking for after the function has been invoked. You don't need to wait for the error message (but you might need to flush output (at many places) if you don't see any error message and you want to pinpoint the origin). So ensure that output buffering is disabled.

hakre
  • 193,403
  • 52
  • 435
  • 836
2

It probably doesn't trigger an error because what you've printed so far it too short and was still buffered before your header call.

Try outputting some more data, for example:

echo str_repeat('a', 10000);

And then try to output some header. You should then see the expected PHP error (assuming your error reporting settings are tuned properly).

sagi
  • 5,619
  • 1
  • 30
  • 31
  • Technically correct, but I feel that this is ignoring the bigger problem. Why is he using headers after he has outputted any HTML? Why are their blank lines within the output before any HTML is placed on screen. These are fundamental problems that should be fixed first. – Mark Tomlin Jul 13 '11 at 21:31
  • 1
    He is actually trying to do something pretty clever - he tries to send the header hoping to trigger the PHP error, so he can understand what outputs these blank lines and fix it. He is not getting the expected error, probably because of the output buffering, hence my response. – sagi Jul 13 '11 at 21:33
  • Yes, he has replied to my answer with that statement also. Very interesting. But as a general rule, I find it easier to just check the top's and bottoms of files, for blank lines, check in between `?> – Mark Tomlin Jul 13 '11 at 21:39
1

I've got the same problem on Drupal (lots of iles), I try several of the above answers without any results.

Finally I found the find way (cf. Elegant way to search for UTF-8 files with BOM?), it points out a dumb mistake : spaces at the beggining of a module file :

find . -type f -name '*.module' -print0 | xargs -0r awk '/^ / {print FILENAME}{nextfile}'
find . -type f -name '*.php' -print0 | xargs -0r awk '/^ / {print FILENAME}{nextfile}'
find . -type f -name '*.inc' -print0 | xargs -0r awk '/^ / {print FILENAME}{nextfile}'
Community
  • 1
  • 1
Teenage
  • 210
  • 2
  • 6
0

I just had a similar problem with hidden BOMs, but this applies to blanks lines and other spurious characters as well, so I thought to add here my findings.

Adding a fake header(""); call in the code is the best way to find where the output started, but... most likely, the PHP configuration has output_buffering enabled by default. Check this out.

By adding this at the beginning of your script:

if (ob_get_level()) ob_end_clean();

will turn off output buffering and make the header() call complain and say where the output started.

savedario
  • 902
  • 15
  • 26
0

Display errors by putting these lines somewhere in your PHP:

error_reporting(E_ALL);
ini_set('display_errors','on');

This will trigger that header error!

It's probably at the end of the PHP file; you should consider removing the ending PHP tag (?>) to eliminate this problem.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Dunhamzzz
  • 14,682
  • 4
  • 50
  • 74
0

To answer you're question directly, any echo, or print statement, or any function that returns results directly to the standard output will cause output to start. Also if you have any HTML or text or blank lines before an opening <?php tag this will cause output to start.

You can fix this directly by adding a ob_start() at the top of your entry document just below a <?php tag. And adding a ob_end_flush() at the very end of your document. That would look like this.

Add this to the very top of your document:

<?php
    ob_start();
?>

Add this to the very bottom of your document:

<?php
    echo ob_end_flush();
?>

This allows you to keep the current code that you do have, and output headers where ever you need them within the code without getting that error.

Mark Tomlin
  • 8,593
  • 11
  • 57
  • 72
  • What I mean is I **want** the errors to appear so that I can pinpoint the output. I never used ob_start() before, but it sounds promising. – Linksku Jul 13 '11 at 21:36
  • @Linksku, or in the worst case, use this solution to trim() the buffered output – Saic Siquot Jul 14 '11 at 12:26
-1

This can occur if you have any empty lines above the very first <?php in your code (assuming you have it at the 'top' of you file)

helloandre
  • 10,541
  • 8
  • 47
  • 64