Sunday, September 9, 2012

PHP warnings about headers and the session_start function

If you read the voluminous amount of information available on the internet, you will learn that the HTTP Header must be sent before any other HTML code is processed. This also includes blank lines. This enforcement by PHP came about with PHP 4.3 and it can cause some headache if you are dealing with sessions and/or header redirects.

I have been working on a PHP site for someone and have actually had to deal with this more than once. The indicator that something is wrong is a 'Warning' message that will be displayed in the browser that looks similar to:

Warning: Cannot modify header information - headers already sent by (output started at /mysite/htdocs/utils/config.php:37) in /mysite/htdocs/controllers/processLogin.php on line 27

For the purposes of this post, the content of these files do not matter so much. However, to be clear about what I do have in my code:

- in config.php, which I use solely for back end DB connections, I have at the top of my file:
           session_start();
        ...
   ?>


- in processLogin.php, I have:
   if ($count == 1) {        
        $_SESSION['username'] = $myusername;        
        header("location: ../index.php?p=welcome");
    } else {
        header("location: ../index.php?p=autherror");

where the first 'header()' statement is the line 27 referenced in the warning message above.

Having the header() function after a session_start() call CAN cause the same warning in certain conditions. The bottom line with this is that at the start of each file where it is needed you should have the session_start() call before anything else, PHP or HTML. However, THIS was NOT my problem.
If you noticed in the 'Warning' line states that the output was started at line 37 of config.php. Interestingly enough, my file only had 32 lines of code, including the opening and closing PHP tags, the closing tag being the 32nd line. What I didn't realize was that I had those extra lines after the closing tag, although I had immediately noticed that the line being reported was a higher number than the lines of code in that file.

So, as you may have guessed, the problem was the blank lines. Even though I had the session_start() at the correct locations, the blank lines were being processed in-between the session_start() and the header() calls, thus violating the standard that the HTML header MUST be the first thing sent  for the page.