3

I am using MaxMind's GeoIp2 PHP to redirect website visitors based on their country.

I have managed to get the redirect working so that:
US visitors go to http://www.example.com/us
Malaysian visitors go to http://www.example.com/my
All other visitors go to http://www.example.com

The problem is that I only want to redirect visitors once. After they are on the website, if they navigate to http://www.example.com they should be able to do so without getting redirected, regardless of their country.

This is so that both humans and spiders can still have the freedom to visit pages that are not targeted at their country.

I have tried using the suggestion to a similar problem as answered here but the question there is regarding different domains for different countries instead of different paths so the solution doesn't work for me.

The code:

<?php 
require_once '../vendor/autoload.php';
use GeoIp2\Database\Reader;

$reader = new Reader('/usr/local/share/GeoIP/GeoLite2-Country.mmdb');

$record = $reader->country( $_SERVER['REMOTE_ADDR'] );

try {
  $country = $record->country->isoCode;

  switch((string)$country) {
    case 'US':
      $url = "http://www.example.com/us";
      break;
    case 'MY':
      $url = "http://www.example.com/my";
      break;
    default:
      $url = "http://www.example.com";
  } 

  if (strpos("http://$_SERVER[HTTP_HOST]", $url) === false)
  {
      header("Location: ".$url);
  }

} catch (Exception $e) {
  // Handle exception
}
?>

Any help is greatly appreciated.

Community
  • 1
  • 1
Leb
  • 117
  • 1
  • 9

1 Answers1

2

You could use a cookie to keep track of:

  1. if the visitor has been redirected before
  2. the country that the visitor has been redirected to before

If the spiders are clever, they will make use of the cookies too (Ref: Can Bots/Spiders utilize Cookies?).

So you could write your logic like so:

<?php 
require_once '../vendor/autoload.php';
use GeoIp2\Database\Reader;

$cookie_name = "country_code";
session_start();


if (isset($_GET['check']) && $_GET['check'] == true) {

  if (isset($_COOKIE['test_cookie']) && $_COOKIE['test_cookie'] == 'test') {

    if(!isset($_COOKIE[$cookie_name])) {

      $reader = new Reader('/usr/local/share/GeoIP/GeoLite2-Country.mmdb');

      $record = $reader->country( $_SERVER['REMOTE_ADDR'] );

      try {

        $country = $record->country->isoCode;

        switch((string)$country) {
          case 'US':
            $url = "http://www.example.com/us";
            break;
          case 'MY':
            $url = "http://www.example.com/my";
            break;
          default:
            $url = "http://www.example.com";
        } 

        $cookie_value = "" . (string)$country;

        setcookie($cookie_name, $cookie_value, time() + (86400 * 30), "/"); // 86400 = 1 day
        if(!isset($_GET['cookies'])){

          header('Location:/info.php?cookies=true');
        }
        if (strpos("http://$_SERVER[HTTP_HOST]", $url) === false)
        {
            header("Location: ".$url);
        }

      } catch (Exception $e) {
        // Handle exception
      }

    } else { //cookie is set no redirect

    }

  } else { //no cookie support, no redirect

  }

} else {

  setcookie('test_cookie', 'test', time() + 3600);

  header("location: {$_SERVER['PHP_SELF']}?check=true");
}


?>
Community
  • 1
  • 1
AEQ
  • 1,339
  • 1
  • 16
  • 20
  • Thanks for the advice! I've tried your solution but US visitors still keep getting redirected to the /us site. I think the problem probably lies with the following section of code though I'm not 100% sure: if (strpos("http://$_SERVER[HTTP_HOST]", $url) === false) { header("Location: ".$url); } – Leb May 27 '15 at 13:09
  • They shouldn't be redirected at all once the cookie is set, they should be going to the "//cookie is set no redirect" section of code. If the users browser doesn't have their cookies enabled, then they will be redirected all the time. – AEQ May 27 '15 at 13:29
  • You're right, had some issues with deleting the cookies with Chrome when running tests. Tested your solution out with Safari (easier to delete/check on cookies) and everything works like a charm. – Leb May 27 '15 at 14:08
  • I added a "cookie support" check but it adds a redirect in order to detect, inspired by : http://stackoverflow.com/a/9448539/2139770 – AEQ May 27 '15 at 14:13
  • For Chrome, you just need to inspect the page, switch to Resources tab, expand Cookies, click on your domain, click the cookie, then right-click Delete – AEQ May 27 '15 at 14:24
  • Oh yes, I see the Cookies (+ details) in Chrome. The value that was set to country_code is also there so it is easy for testing. Thanks! – Leb May 27 '15 at 14:31
  • You're welcome @Leb, feel free to up-vote everything you found useful :) – AEQ May 27 '15 at 14:33