WordPress IP restriction w/ Header Location Redirect

I have a wordpress site I’m trying to lock down to a set of IPs. I’m using the following code as the first thing in index.php: (IPs obfuscated here)

$matchedIP = 0;
$IP = $_SERVER['REMOTE_ADDR'];

$validIPs = array("x.x.x.x", "x.x.x.x", "x.x.x.x", "x.x.x.x", "x.x.x.x");

foreach($validIPs as $validIP)
{
    if($IP == $validIP)
    {
        $matchedIP = 1;
    }
}

if($matchedIP == 0)
{
    header('Location: http://google.com.au');
}

The IP check works fine, as assorted assertions can confirm. What doesn’t work is the redirect, which never happens. The full index.php is as below:

Read More
<?php

$matchedIP = 0;
$IP = $_SERVER['REMOTE_ADDR'];

$validIPs = array("x.x.x.x", "x.x.x.x", "x.x.x.x", "x.x.x.x", "x.x.x.x");

foreach($validIPs as $validIP)
{
    if($IP == $validIP)
    {
        $matchedIP = 1;
    }
}

if($matchedIP == 0)
{
    header('Location: http://google.com.au');
}

/**
 * Front to the WordPress application. This file doesn't do anything, but loads
 * wp-blog-header.php which does and tells WordPress to load the theme.
 *
 * @package WordPress
 */

/**
 * Tells WordPress to load the WordPress theme and output it.
 *
 * @var bool
 */
define('WP_USE_THEMES', true);

/** Loads the WordPress Environment and Template */
require('./wp-blog-header.php');

//require('./phpinfo.php');

The curious thing is, when commenting out the wordpress blog-header require and including a require to a simple phpinfo page instead, the redirect behaves as expected.

Am I misunderstanding the way PHP’s processing works in some way? Surely it should hit the redirect before it even considers loading any required files below?

EDIT: Windows IIS7 backend, PHP Version 5.2.17, WordPress Version 3.4.2

Related posts

Leave a Reply

2 comments

  1. If you want to make a proper redirect, you have to terminate the script execution after the header-directive:

    if(!in_array($IP, $validIPs))
    {
        header('Location: http://google.com.au');
        exit(0);
    }
    

    The reason is, that if you let WordPress continue its execution, it will send a HTTP status code 200 and the browser will ignore the Location header. Only a sub-set of the HTTP status codes make use of the Location header.

    With the exit in place, PHP stops executing and will automatically send a 302 HTTP status, which tells the browser to redirect to the URL specified in the Location header.

  2. You don’t need a for loop for it

    <?php
    
    $matchedIP = 0;
    $IP = $_SERVER['REMOTE_ADDR'];
    
    $validIPs = array("x.x.x.x", "x.x.x.x", "x.x.x.x", "x.x.x.x", "x.x.x.x");
    
    if(in_array($IP, $validIPs))
    {
        header('Location: http://google.com.au');
        exit(0);
    }
    
    ?>