31
include('header.php');

$name = $_POST['name'];
$score = $_POST['score'];
$dept = $_POST['dept'];

$MyDB->prep("INSERT INTO demo (`id`,`name`,`score`,`dept`, `date`) VALUES ('','$name','$score','$dept','$date')");
// Bind a value to our :id hook
// Produces: SELECT * FROM demo_table WHERE id = '23'
$MyDB->bind(':date', $date);
// Run the query
$MyDB->run();

header('Location:index.php');
    exit;

The above code keeps giving me an issue with the redirect. The error is the following:

Warning: Cannot modify header information - headers already sent by (output started at /Applications/MAMP/htdocs/testygubbins/OO/test/header.php:15) in /Applications/MAMP/htdocs/testygubbins/OO/test/form.php on line 16.

I am totally flummoxed by this. Does anyone know what I should be doing to make it work?

EDIT

header.php code:

<?php
include('class.user.php');
include('class.Connection.php');

$date = date('Y-m-j');

?>
<html>
<head>
    <link rel=StyleSheet href="css/style.css" type="text/css" media=screen>
    <title>Test</title>
</head>
<body>
<div id="page">
Ivan
  • 34,531
  • 8
  • 55
  • 100
Drew
  • 3,194
  • 8
  • 40
  • 62
  • 1
    You can't redirect if you have already sent HTML output. Either use output buffering or replace 'include "header.php"' with the PHP block in header.php. – monzee Jan 08 '09 at 15:46
  • maybe there is problem in header.php, that's why **header** cant redirect. – T.Todua Jul 24 '14 at 08:29

12 Answers12

54

Look carefully at your includes - perhaps you have a blank line after a closing ?> ?

This will cause some literal whitespace to be sent as output, preventing you from making subsequent header calls.

Note that it is legal to leave the close ?> off the include file, which is a useful idiom for avoiding this problem.

(EDIT: looking at your header, you need to avoid doing any HTML output if you want to output headers, or use output buffering to capture it).

Finally, as the PHP manual page for header points out, you should really use full URLs to redirect:

Note: HTTP/1.1 requires an absolute URI as argument to Location: including the scheme, hostname and absolute path, but some clients accept relative URIs. You can usually use $_SERVER['HTTP_HOST'], $_SERVER['PHP_SELF'] and dirname() to make an absolute URI from a relative one yourself:

Paul Dixon
  • 295,876
  • 54
  • 310
  • 348
49

COMMON PROBLEMS:

1) There should be NO output (i.e. echo... or HTML parts) before the header(...); command.

2) After header(...); you must use exit();

3) Remove any white-space(or newline) before <?php and after ?> tags.

4) Check that php file (and also other .php files, that are included) - they should have UTF8 without BOM encoding (and not just UTF-8). Because default UTF8 adds invisible character in the start of file (called "BOM"), so you should avoid that !!!!!!!!!!!

5) Use 301 or 302 reference:

header("location: http://example.com",  true,  301 );  exit;

6) Turn on error reporting. And tell the error.

7) If none of above helps, use JAVASCRIPT redirection (however, discouraged method), may be the last chance in custom cases...:

echo "<script type='text/javascript'>window.top.location='http://website.com/';</script>"; exit;
T.Todua
  • 53,146
  • 19
  • 236
  • 237
  • 3
    exit; or die(); did it for me – brycejl Feb 28 '17 at 16:18
  • 1
    "There should be NO output (i.e. echo... or HTML parts) before the header(...); command" ... save my day, thanks – Pedro P Jan 25 '19 at 00:05
  • You can have output if the "output_buffering" in the php.ini file is set. Mine on my home Debian system is set to 4096. The one on the server I am using states that it has no setting. –  Jul 09 '20 at 18:36
  • The rule is no output _before_ the redirect, but I've noticed all of your answers also prevent output _after_. Do some browsers not redirect correctly if there is output after? – felwithe Apr 28 '21 at 16:31
8

Alternatively, not to think about a newline or space somewhere in the file, you can buffer the output. Basically, you call ob_start() at the very beginning of the file and ob_end_flush() at the end. You can find more details at php.net ob-start function description.

Edit: If you use buffering, you can output HTML before and after header() function - buffering will then ignore the output and return only the redirection header.

ya23
  • 14,226
  • 9
  • 46
  • 43
7

Try This :

**ob_start();**

include('header.php');

$name = $_POST['name'];
$score = $_POST['score'];
$dept = $_POST['dept'];

$MyDB->prep("INSERT INTO demo (`id`,`name`,`score`,`dept`, `date`) VALUES ('','$name','$score','$dept','$date')");
// Bind a value to our :id hook
// Produces: SELECT * FROM demo_table WHERE id = '23'
$MyDB->bind(':date', $date);
// Run the query
$MyDB->run();

header('Location:index.php');

**ob_end_flush();**

    exit;
mostafa
  • 71
  • 1
  • 1
3

Look at /Applications/MAMP/htdocs/testygubbins/OO/test/header.php line 15.

At that position, it makes some output. Fix it. :)

myplacedk
  • 1,574
  • 2
  • 14
  • 19
2

If I understand correctly, something has already sent out from header.php (maybe some HTML) so the headers have been set. You may need to recheck your header.php file for any part that may output HTML or spaces before your first

EDIT: I am now sure that it is caused from header.php since you have those HTML output. You can fix this by remove the "include('header.php');" line and copy the following code to your file instead.

include('class.user.php');
include('class.Connection.php');

        $date = date('Y-m-j');
Gant
  • 29,661
  • 6
  • 46
  • 65
2

You may have some "plain text" somewhere in php files that is interpreted as script output. It may be even a newline before or after the php script tag specifier (less-than + question mark + "php").

Besides, if I remember correctly, according to http specification, the "Location" header accepts only full URLs, not relative locations. Have that in mind too.

macbirdie
  • 16,086
  • 6
  • 47
  • 54
2

Don't include header.php. You should not output HTML when you are going to redirect.

Make a new file, eg. "pre.php". Put this in it:

<?php
include('class.user.php');
include('class.Connection.php');
?>

Then in header.php, include that, in stead of including the two other files. In form.php, include pre.php in stead of header.php.

myplacedk
  • 1,574
  • 2
  • 14
  • 19
1

Your include produces output, thereby making it impossible to send a http header later. Two option:

  1. Move the output somewhere after the include.
  2. Use output buffering, i.e. at the very start of your script, put ob_start(), and at the end, put ob_flush(). This enables PHP to first wait for all the output to be gathered, determine in what order to render it, and outputs it.

I would recommend you learn the second option, as it makes you far more flexible.

Martijn Heemels
  • 3,529
  • 5
  • 37
  • 38
1

also try include_once() instead of include() that can also work

Nisarg
  • 3,024
  • 5
  • 32
  • 54
0

Also see your php file text encoding. Mine was UTF-8 with BOM and it prevented the script to work. But now works flawlessly after removing the BOM...

Rathakrishnan Ramasamy
  • 1,612
  • 2
  • 25
  • 46
julifos
  • 142
  • 1
  • 2
  • 10
-1

Try redirection with JavaScript:

<script type="text/javascript">
  window.location.href='index.php';
</script>
Jason Plank
  • 2,336
  • 5
  • 31
  • 40
Zaib
  • 15
  • 1