Often times, we need to redirect users from one page to another. May be you updated an old blog post, and the updated version exists at a new URL.

Or you may want to make a redirect after showing a count down timer, as in the case of file downloads.

Whatever the scenario be, in this post, we’ll discuss about redirecting web pages using PHP, along with the alternatives.

How it Works - The HTTP Location header

The important thing you need to understand here is, a redirection is performed by sending the HTTP Location header. A web page can include multiple headers in the form of key-value pairs. The Content-Length header is another example.

The specification for the Location header is defined in HTTP/1.1. You can find it here. A normal page load does not include the Location header. So the browser stays on the same page.

The Location header can have an absolute or relative URL as its value, which is the redirection destination.

Location: http://example.com/new-page.php

Or:

Location: new-page.php

Tip: In Chrome, go to Inspect > Network > (click on the page name) > Headers > Request Headers > View Source to view all the headers of a page.

PHP offers a built-in function called header(), which allows you to set any HTTP header, including Location.

PHP header() function

The header() function accepts three arguments:

  1. the header string
  2. replace - boolean value indicating whether to replace the existing header or not
  3. response_code - the default response code is 302, which is one of the status codes for a temporary redirect.

Suppose we have a page at the address example.com/old-page.php. And we want to redirect it to example.com/new-page.php.

To do that, you can add the following at the top of old-page.php.

<?php

header('Location: new-page.php');
die();

/*
remaining code goes here, which won't be executed
*/

It’s as simple as that!

When the browser receives the location header along with the URL, new-page.php in this case, it gets redirected. Also, you might have noticed the die() function call followed by that. So, there mainly three things you should keep in mind when using the header().

  • always call die() or exit() after setting the Location header
  • the header() call must be put before any output, such as HTML, echo, print(), etc.
  • the default status code is 302

Calling die() or exit; makes sure the remaining code below the redirect does not get executed. Suppose you are redirecting an unauthenticated user back to the login page from a protected page. If there is not die(), then some part of the remaining code can get executed, revealing some sensitive information.

There can be slight delays between PHP asking the web server to send the header, and the server actually sending the header. In between, the code can continue executing, resulting in unwanted behaviors.

Note: as per PHP documentation, both die() and exit() are the same.

If you want to use a different status code, for instance 301 Moved Permanently or 308 Permanent Redirect, then there are a couple of ways to do that.

One way is to make use of the other parameters available with the header() function:

<?php

header('Location: new-page.php', true, '301');
die();

Or you can set it separately as well:

<?php

header('HTTP/1.1 301 Moved Permanently');
header('Location: new-page.php');
die();

You can even combine it with the $_SERVER global variable if not sure about the HTTP version:

<?php

header($_SERVER['SERVER_PROTOCOL'] . ' 301 Moved Permanently');
header('Location: new-page.php');
die();

Another alternative is to use the http_response_code() function:

<?php

http_response_code(301);
header('Location: new-page.php');
die();

As you can see, the function receives the status code as an integer argument.

Delayed Redirect using the refresh header

The above method instantly redirects the user to the new page. But there can be cases when you want to display a message, then redirect after some delay.

The use of the Location header is not possible in this case as it must come before any output.

What you can do instead is to use the refresh header:

<?php

header('refresh:5;url=new-page.php');

?><!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Old Page</title>
</head>
<body>
    <h1>Old Page</h1>
    <h2>You'll be redirected in <span class="count">5</span> seconds...</h2>
    <script>
        var countElement = document.querySelector('.count');
        var count = 5;
        var handler = () => {
            countElement.innerHTML = --count;
            if(count === 0) clearInterval(timer);
        };

        var timer = setInterval(handler, 1000);
    </script>
</body>
</html>
die();

Note the Javascript code at the bottom, which displays a countdown timer.

However, various sources say that the HTTP refresh header is not a standard. Anyways, most browsers recognize it. So it works.

It is similar to the meta http-equiv=“refresh” tag in HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Redirecting...</title>
    <meta name="robots" content="noindex">
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <meta http-equiv="refresh" content="0; url=new-page.php"/>
</head>
</html>

Or if you prefer a pure Javascript solution, then you can use the window.location.replace() method:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Old Page</title>
</head>
<body>
    <h1>Old Page</h1>
    <script>
        window.location.replace("new-page.php");
    </script>
</body>
</html>

Conclusion

I hope the post helped you to learn about PHP redirects and other alternatives.