Accessibility
Adobe
Sign in Privacy My Adobe

Community Publishing

Created:
2009-08-03
Last Updated:
2010-03-06
by
User Level:
Intermediate/Advanced
Products:
Dreamweaver CS4,CS3,8

Need more tips and tutorials?


PHP development: why redirects don't work (headers already sent)

Although this article focuses on the PHP code generated by Dreamweaver, the information applies equally to PHP code that you have written yourself or copied from a book or tutorial.

The problem

One of the most puzzling error messages for newcomers to PHP is "Cannot modify header information - headers already sent." It's often triggered if you make changes to the code generated by Dreamweaver's PHP server behaviors, such as Insert Record, Update Record, or Log In User. What happens is that the database is correctly updated, but the user isn't redirected to the correct page. If the PHP display_errors directive is turned on, you see the error message about headers already sent; if display_errors is off, you're left scratching your head wondering why the redirect didn't work.

What causes it

When somebody requests a web page, the server responds by sending the page headers. These contain important information that tell the browser how to handle the page, and they must be sent before anything else. That's what the error message is telling you: the headers have already been sent, so it's too late to try to modify them.

Dreamweaver's server behaviors use the PHP header() function to redirect users to another page after interaction with the database. They also use session_start() to create a PHP session when logging in a user or restricting access to a page. Both header() and session_start() must be called before any output is sent to the browser. The code generated by Dreamweaver is aware of this restriction, and doesn't trigger the error. It's when you make changes to the Dreamweaver code, either intentionally or accidentally, that the problem can arise.

The cure

What confuses a lot of people is the term "output." It means anything sent to the browser that isn't part of the headers, even a single blank space or newline character. Dealing with the problem involves checking for any of the following:

  • Any HTML output, including the DOCTYPE declaration or any HTML tag, including the head of the page
  • Extra whitespace before the opening PHP tag of the page, or outside the PHP tags of an include file
  • Using print() or echo before calling header() or session_start()
  • Using virtual() to include files
  • Using the byte-order mark (BOM) at the beginning of a page
Detect and eliminate whitespace

One of the most common causes of this problem is adding an extra line after the closing PHP tag in an include file, such as the one Dreamweaver creates in the Connections folder with details of your MySQL connection.

If you have problems with page redirects not working or see the "headers already sent" error, open any include files, and check for whitespace outside the PHP tags. An easy way to spot newline characters at the end of an include file is to look at the line numbers. If there are any line numbers after the closing PHP tag, that's where your problem lies, as shown in the following screenshot:

Include file

Get rid of the extra line(s) by pressing Backspace until your cursor is immediately to the right of the closing PHP tag. Also make sure there is nothing before the opening PHP tag on any page.

Remove code that outputs text

Output includes any HTML or text output to the browser. Make sure your code doesn't use print() or echo before the call to header() or session_start(). When troubleshooting other problems, it's common to use print() or echo to display the value of a variable. It's easy to forget to remove them or comment them out.

Replace virtual() with require_once()

When you set up your site definition in Dreamweaver to use links relative to the site root, Dreamweaver uses virtual() to include the MySQL Connection file. This is an Apache-only function that uses a site-root-relative link to include a file. Unfortunately, it frequently triggers output, preventing header() and session_start() from working.

Simply replace virtual() with require_once() and a document-relative link to the MySQL Connection file. For example, if your page is in the site root and uses a connection called myConn, change the following:

<?php virtual('/Connections/myConn.php'); ?>

like this:

<?php require_once('Connections/myConn.php'); ?>

Note that the leading forward slash has been removed from the file path. If your page is in a subfolder of the site root, you will need to adjust the file path accordingly by adding ../ at the beginning like this:

<?php require_once('../Connections/myConn.php'); ?>

If you have difficulty working out the correct document-relative path in Dreamweaver, delete the path, and position your cursor between the quotes. Right-click, and select Code Hint Tools > URL Browser from the context menu. Then click Browse, and navigate to the connection file. Make sure the Relative to popup menu is set to Document, and click OK.

Remove the BOM

A less common cause is using a BOM at the beginning of your web pages. To check whether a page is using a BOM, open Page Properties (from the Modify menu or the Property inspector), and select Title/Encoding from the Category list on the left. Make sure the checkbox labeled Include Unicode Signature (BOM) is NOT selected, as shown here:

Page Properties dialog box

If the checkbox is selected, you can change the default setting for new documents in the New Document category of the Preferences panel, which can be accessed from the Edit menu on Windows or the Dreamweaver menu in the Mac version.

Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License