Website development and design blog, tutorials and inspiration

Blocking Website Access by Country with PHP

Using PHP to Block Website Access by Country

Written By on in PHP 37

Blocking Website Access by Country with PHP

374 words, estimated reading time 2 minutes.

A while back one of my websites came under a massive attack receiving an additional 1000+ hits per day, all malicious construction and all from one particular country. Since I was fast approaching my allocated bandwidth limit I had to take action to stop them accessing the site, and fast!

I decided to take the drastic action to block the entire country from accessing my site; I have had not legitimate visits from that country and can probably do without. Whilst reading about blocking a country (or extension) everybody talks about how difficult and time consuming it would be using .htaccess and blocking IP address ranges manually.

I have found an easy method for blocking a country, it only takes a few lines of code and has virtually no server load, so read on and I'll tell you.

It works like this:

Goto for a look at "country identification without databases." Download the complete database (~540k) and extract it to a folder on your website. It will create a folder called 'ip_files'.

Next use this bit of PHP at the top of each of your pages. (Code provided on

  3. else
  4. $ip = $_SERVER['REMOTE_ADDR'];
  6. $two_letter_country_code=iptocountry($ip);
  8. function iptocountry($ip)
  9. {
  10. $numbers = preg_split( "/./", $ip);
  12. include("ip_files/".$numbers[0].".php");
  13. $code=($numbers[0] * 16777216) + ($numbers[1] * 65536) + ($numbers[2] * 256) + ($numbers[3]);
  15. foreach($ranges as $key => $value)
  16. {
  17. if($key<=$code)
  18. {
  19. if($ranges[$key][0]>=$code)
  20. {
  21. $country=$ranges[$key][1];break;
  22. }
  23. }
  24. }
  26. if ($country=="")
  27. {
  28. $country="unknown";
  29. }
  31. return $country;
  32. }

Then, add this little blocking script at the end of the code above:

  1. if ($two_letter_country_code=="US")
  2. die();

You should replace US with the two letter country code for the country you are trying to block.

I have taken this a bit further on mine, in that I check for a valid session, and if not found, run all the checks and create a session. This prevents the script from running every page load - just when a new visitor connects.

  2. <?php
  3. session_start();
  4. if (!isset($_SESSION['FirstVisit']))
  5. {
  6. if ($two_letter_country_code=="US")
  7. die();
  8. else
  9. $_SESSION['FirstVisit'] = 1;
  10. }
  11. ?>p

Of course, this isn't a perfect solution and will only protect your PHP pages, but in an emergency?

Note, you can find a list of country codes listed in countries.php within ip_files.

Last updated on: Wednesday 21st June 2017

Did you Like this Post? Why not Like us on Facebook?


  1. Anthony

    Here's my contribution full contribution. THIS answers a lot of searchers questions and we use it now... A "Thank you
    will suffice ;-)

    1. Unzip files to a new folder. Should have something like | New_Folder | ip_files
    2. Create a database in mysql and call it whatever but for example "poofoo". Table is: "peewee"
    Columns: id, ip, date (fix it how you like)

    I created another table to actually log what is blocked from the block list to check against. The goal of this is to simply block either everyone but, country and/or single ip addresses. Yes, it's programmed to accept 123.45, 123.4, 123.456 or even 123. No need to type the whole ip unless you want to block that particular one or you can just block the whole node if i'm saying that right... Here we go. a nice thank you kindly would suffice, no paypal needed.

    A. Create a connection file in the "new folder" directory | connector.php

    1. <?php
    2. $dbase = 'poofoo'; // DATABASE NAME
    3. $host = 'hostname'; //DATABASE HOST LOCATION/SERVER
    4. $user = 'theuser_foo'; //USER NAME
    5. $pass = 'texasroadhouse'; //PASSWORD
    6. $conn = mysqli_connect($host, $user, $pass, $dbase) or die (mysql_error());
    8. ?>


    B. Create a new file within the "new folder" directory | blocker.php

    1. <?php
    2. ini_set('display_errors', 'Off');
    5. $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    7. else
    8. $ip = $_SERVER['REMOTE_ADDR'];
    10. $two_letter_country_code=iptocountry($ip);
    11. function iptocountry($ip)
    12. {
    13. $numbers = explode( ".", $ip);
    14. include("ip_files/".$numbers[0].".php");
    15. $code=($numbers[0] * 16777216) + ($numbers[1] * 65536) + ($numbers[2] * 256) + ($numbers[3]);
    17. foreach($ranges as $key => $value)
    18. {
    19. if($key<=$code)
    20. {
    21. if($ranges[$key][0]>=$code)
    22. {
    23. $country=$ranges[$key][1];break;
    24. }
    25. }
    27. }
    29. if ($country=="")
    30. {
    31. $country="unknown";
    32. }
    34. $cur_country = $country;
    36. include ("connector.php");
    37. $query = "SELECT * FROM peewee";
    38. $result = mysqli_query($conn, $query);
    40. if (!$conn) {
    41. die;
    43. }
    45. while($row = mysqli_fetch_assoc($result)) {
    47. $cblock = $row['name'];
    48. //This if statement searches for a string variable and once found, blocks anything else not US based.
    49. if($cblock === "USA ONLY" and $country != "US") {
    50. mysqli_free_result($result);
    51. mysqli_close($conn);
    52. //send their butts to somewhere else and be done with it
    53. echo "<META http-equiv='refresh' content='0; URL='>";
    54. }
    56. //If they are US based but are on the block list
    57. $blocked = $row['blocked_country_by_ip_set'];
    59. }
    60. //If the database row matches the country array and the boolean of $blocked is true...
    61. if($cblock === $country and $blocked === 1) {
    62. $time = date('Y-m-d H:i');
    63. $insert = "INSERT IGNORE INTO table_of_blocked_logs VALUES ('','$ip','$ip',$time')";
    64. if ($conn->query($insert) === TRUE) {} else {
    65. //DO something here not show the error to the person you are actually wanting to block just in case
    66. exit;
    67. }
    69. mysqli_free_result($result);
    70. mysqli_close($conn);
    71. echo "<script>alert('Please take a moment to review a very special offer we are running before you review!')</script>";
    72. echo "<META http-equiv='refresh' content='0; URL='>";
    74. }
    75. }
    77. // The below bracket might be one to many, if you get the white screen of php death, remove it.
    78. }
    80. ?>


    C. Now at the top of your index.php page(rename to *.php for those using .htm,.html), you can paste the following;

    <?php include "blocker.php" ?>

    Use above for top of the tree and respectfully use your switch as needed when inside directories.
    <?php include "../blocker.php" ?>

  2. Shreyansh Jha
    Shreyansh Jha

    For those who are looking to block multiple countries with this code I have a solution for you. However, I have not tested it yet but it should work.

    Step 1: Store country codes in database that you want to block. If you do not want to use database then use array directly or some other methods you like. But I prefer storing country codes in database.

    Step 2: Extract the codes from database and store it in a variable.
    Example: $country_codes_to_block = $row['block_countries']; // Fetched from database.

    Step 3: Replace the code

    if ($two_letter_country_code=="US")


    if (in_array($two_letter_country_code, $country_codes_to_block))

    Step 4: Done. This should block all the countries whose country codes you have stored in database.

    Still not clear? Sorry, I can't be more clear than this. I made it as much simple and easy to understand as possible. Now apply some brains. Happy coding ;)

  3. brody

    is there a reason why i'm getting Fatal error: Call to undefined function iptocountry()

    for this line of code " $two_letter_country_code=iptocountry($ip); "

  4. jukka

    the preg_split should be "/./"

    toright-toleft-dot-toright (sorry for bad english)
    $numbers = preg_split( "/./", $ip);

  5. Deepak

    Fatal error: Cannot redeclare iptocountry() (previously declared in /home/u475022455/public_html/head.php:61) in /home/u475022455/public_html/head.php on line 85

    give me solution

  6. Miki

    There is a website called that does country and ip blocking pretty smoothly......

  7. Grgo

    Thanks for that. It works good for me over a year, but now I would like to add another country.
    I wonder how you block 2 countries.
    Thanks, G

  8. adam lee
    adam lee

    i want block some country's a list of them and any ip or a visitor log in to my page from this country's i want send them to a link .
    so how i can do that ?
    if any one here plz reply me bcz i need it to much .

    and thank you
    adam lee

  9. Ben

    if ($two_letter_country_code != "US" || !strstr(strtolower($_SERVER['HTTP_USER_AGENT']), "googlebot"))

    i think this is working. code above allowing me to register at google webmaster tools.

  10. Ben

    Anyone using this with cloudflare? Is it working?

  11. Neil

    Hi Tim,

    Is it possible to block and entire country (say India) yes let one specific IP address from India through?

    Many thanks,

    1. Tim Trott
      Tim Trott

      Hi Neil

      You could do something along the lines of:

      $allowed = array('', '');

      if (($two_letter_country_code=="IN") && (!in_array($ip, $allowed))
      // do block here
      // do allow here

      Note: This has not been tested but should get you going.


  12. Vanessa

    Im in CA USA and my block code reads:

    if ($two_letter_country_code!="US")

    However - IM dying..... I think I need an updated database but I cant find the correct DB in the php format on

    Any recomendations would be fantastic.

  13. joe

    I appreciate the help here. My webhost directed me to this link.

    With that said, I am a total noob when it comes to website building/editing.

    I know the above suggestion may sound simple to most of you. But is there a way to dumb it down to someone at my level. I am using wordpress and am a little bit familiar with using an FTP client to modify the coding of the site/as well as doing it thru the WP editor function.

    So, I am reasonably confident I can download the file and get it over to my website via FTP client. I assume I just put it in primary folder for the entire website.

    Once I do that, how do I put the php code into every page on my site to keep it blocked? I have dozens of files with a .php extension on my site.

    Thank you for your patience and your help.

  14. Joey

    PHP5 turns off the ability to use the include() statement for security reasons by default. As a result, it won't pull in the geoip data. Can you, or anyone, suggest an alternative to using the include() statement? Thanks! Joey

    1. Tim Trott
      Tim Trott

      I've not heard of PHP5 disabling include before, is this a particular "feature" of your hosting provider? Do you get any error messages when you use it?

      You could try include_once instead. This function will check to see if the file has already been included and if it has ignore the request instead of throwing an error.


  15. parisa

    Thank you so much
    it was so usefull;

  16. mark dedrick
    mark dedrick

    Could you please post the code for this "I have taken this a bit further on mine, in that I check for a valid session, and if not found, run all the checks and create a session" ?. I'm not good at php and don't know how to implement that. Thanks in advance

    1. Tim Trott
      Tim Trott

      Hi Mark,

      That's going back a bit since I used this code. I'll have a dig through my backups and post what I find.


  17. John

    Thank you. This method has been recommended by the Hostgator support forum, so you must be doing something right!!

  18. ben

    How do you allow google bot etc in this script?

  19. themonleymixer

    I am trying to include this in wordpress and am having a but of trouble, I think it has to do with how wordpress sees directories
    $ip = $_SERVER['REMOTE_ADDR'];


    function iptocountry($ip)
    $numbers = preg_split( "/./", $ip);

    $code=($numbers[0] * 16777216) + ($numbers[1] * 65536) + ($numbers[2] * 256) + ($numbers[3]);

    foreach($ranges as $key => $value)

    if ($country=="")

    return $country;
    if ($two_letter_country_code!="US")

    this is what i used to block all non us and this is the result


    Warning: include(ip_files/.php) [function.include]: failed to open stream: No such file or directory in /home/superbha/public_html/wp-content/themes/anonymous-elegance/header.php on line 17

    Warning: include(ip_files/.php) [function.include]: failed to open stream: No such file or directory in /home/superbha/public_html/wp-content/themes/anonymous-elegance/header.php on line 17

    Warning: include() [function.include]: Failed opening 'ip_files/.php' for inclusion (include_path='.:/usr/lib/php:/usr/local/lib/php') in /home/superbha/public_html/wp-content/themes/anonymous-elegance/header.php on line 17

    Warning: Invalid argument supplied for foreach() in /home/superbha/public_html/wp-content/themes/anonymous-elegance/header.php on line 20


  20. tuba

    thank you for this tutorial!

    I don't want to block any country rather I would like to redirect users to a specific page based on country. Surely helpful.

  21. Spyros

    So glad I found this, I was trying to use an htaccess method and it wouldn't work. Great article, bookmarked for the future :D

  22. Harcourt

    Even though this is an old topic I thought I'd add to it...

    1. You can run PHP on HTML pages by using a "force-type" tag in .htacess, like this:

    1. AddHandler application/x-httpd-php5 .html

    or if that doesn't work...

    2. SetHandler application/x-httpd-php5 .html

    This tells the Server to treat all of your html pages like they are php pages. Only use one, not both!

    This adds an extra load to your Server so you may want to restrict it to certain pages by adding the (FILES index.html) limiter.

    Rather than putting it on every page, use the "include" function at the top of each page, this way you can make changes very quickly if you need to.

    My web pages *were* getting hammered by spammers and hackers from the RIPE and APNIC networks. So I went looking for a *country blocking* system and found this.

    I created my own script that does the same thing, but it uses an entirely different setup. I also use other methods to block hits from some troublesome ISPs.

    So far I haven't had any visits from RIPE or APNIC since using these codes. :-D

  23. shivi

    Can i use this code for html as well php pages to block some of the countries from viewing the data.?

    1. Tim Trott
      Tim Trott

      The code will only run through the PHP engine, so to run it on html pages you would need to have these processed via PHP. Alternatively you may be able to get jQuery or similar framework to perform the same task client side.

  24. achmad

    I'm not php proficient, I just wanted to block 2 country for example Uk and Greanada, how to write the code in the end of the script ?

  25. Prema

    Thanks very much for a very useful script.
    Noticed that the script fails on php 5 with the ip split.
    We rewrote that tiny section using explode instead
    and it works fine on our site.

    $numbers = preg_split( "/./", $ip);
    $numbers = explode( ".", $ip);

    1. ben

      Allow spesific country with
      if ($two_letter_country_code != "DE")

      My question: Is this good for google bot and seo?

    2. faryit

      Thank you :)

  26. Daniel

    I need this, but I am php challenged. :) Does the above code block the US, or does it block everything except the US? I need to block ALL countries EXCEPT the US. If anyone reading this can help me, I can be contacted at daniel "@" . Thx!

    1. Tim Trott
      Tim Trott

      The code above will block the US. To reverse this and block everything apart from US try the following:

      <pre lang="php">if ($two_letter_country_code != "US")

      Hope that helps

  27. Gytis

    my friend modify original code and you can use few countries now :

    2. $value){
    3. if($key=$code){$two_letter_country_code=$ranges[$key][1];break;}
    4. }
    5. }
    6. if ($two_letter_country_code==""){$two_letter_country_code="unkown";}
    7. return $two_letter_country_code;
    8. }
    9. ?>
  28. Chris

    How have you overcome the issue that the IP to country database changes almost daily? Have you looked at any of the services and connecting to them?

  29. peter

    going to try it now, I had someone stalk me from Italy, had some php ip blocks but she kept on using different machines.

    A country block is what I am looking for.


Leave a Reply

Your email address will not be published.