Ok here is a cool trick I figured out that I hope will be helpful to someone:
What if you wanted to block all the incoming ip addresses from a given country to a given site using only PHP and mySQL (without using .htaccess, etc.) and be able to log who you blocked into your mySQL database?
First, you need to have a white list or a black list. I got mine from http://software77.net/geo-ip/ because they were free, based off of countries and worked pretty darn well.
For myself, I used the x.x.x.x-y.y.y.y option, cut out the headers and dropped the text file onto my server, then I made a little script to load them into a table in mydatabase:
<?php
include "myconfig.php"; //this contains my db connection info --use your own here
include "openmyDB.php"; //this opens up my db connection --use your own here
//clear out the table first
mysql_query("DELETE FROM myallowedIp")or die(mysql_error());
//get all the ip ranges from the text file I put on the server
$validAddressList = file_get_contents('validipAddresses.txt');
//split them up into an array
$validAddresses = explode("\n", $validAddressList);
//put each element of the array into the db
foreach ($validAddresses as $validAddressRange)
{
//trim it
$validAddressRange = trim($validAddressRange);
//get the two halves of the range
$fromAndTo = explode("-", $validAddressRange);
//put them into the db. NOTE: I am converting them into longs so thatI can quickly compare them later
$myQuery = "INSERT INTO myallowedIp (ipaddressFrom, ipaddressTo)
VALUES ('".ip2long($fromAndTo[0])."', '".ip2long($fromAndTo[1])."')";
//echo $myQuery."<br>";
mysql_query($myQuery)or die(mysql_error());
}
include "closemyDB.php"; //this closes my db connection --use your own here
?>
I recommend taking that script off your server once you are done loading it up for security purposes.
Now that I have it all loaded into my db, I can now query that table every time a user shows up at my site and turn them away or allow them in (depending on if I want to treat my address ranges like a whitelist or a blacklist)!
To do this, first you get the ip address of the user (here I keep it around as a session variable, but do whatever you want):
<?php
session_start();
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) //to check ip is pass from proxy
{
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
$ip=$_SERVER['REMOTE_ADDR'];
}
$_SESSION["REALIPADDRESS"] = $ip;
?>
Then, you compare it against your table (assuming you have already opened up your db connections):
$allowResult = mysql_query("SELECT * FROM myallowedIp WHERE
ipaddressFrom <= '".ip2long($_SESSION["REALIPADDRESS"])."' AND
ipaddressTo >= '".ip2long($_SESSION["REALIPADDRESS"])."'")or die(mysql_error());
if($allowRow = mysql_fetch_array( $allowResult ))
{
//if this is a whitelist, you can come in...(put other code here as you want)
}
else
{
//not on whitelist...
//send them somewhere else or whatever you want. Note: only use the header() command if you have not sent ANYTHING to the user yet. If it is not working, check that first.
header ('HTTP/1.1 301 Moved Permanently');
header ('Location: http://www.google.com/');
exit();
}
I hope that helps someone! Take care and have fun developing!
EDIT: I had to move the site around where I use this, and I decided to change how I did it to make it more intuitive for me to test. Instead of storing the allowable IP addresses as LONGs, I stored them as VARCHAR with a max size of 15, so that my code snippet above would look like this instead:
$myQuery = "INSERT INTO myallowedIp (ipaddressFrom, ipaddressTo)
VALUES ('".$fromAndTo[0]."', '".$fromAndTo[1]."')";
Then, when it comes time to check if something matches (or doesn't match), I do this instead, using mySQL's INET_ATON to compare them instead of PHP's ip2long:
$allowResult = mysql_query("SELECT * FROM myallowedIp WHERE
INET_ATON(ipaddressFrom) <= INET_ATON('".$_SESSION["REALIPADDRESS"]."') AND
INET_ATON(ipaddressTo) >= INET_ATON('".$_SESSION["REALIPADDRESS"]."')")or die(mysql_error());