In diesem Artikel zeige ich, wie man effizient das zugehörige Land einer IP-Adresse ermitteln kann.
Als erstes brauche ich eine kostenlose Datenbasis. Nach einiger Zeit des Suchens halte ich IP-to-Country.com für die beste Quelle. Ich lade mir die IP-to-Country Database herunter und entpacke sie.
Da ich nicht jedes mal die gesamte CSV-Datei durchsuchen möchte, erstelle ich eine MySQL-Tabelle ip_locations:
CREATE TABLE `ip_locations` (
`id` int(10) unsigned NOT NULL auto_increment,
`from` int(10) unsigned NOT NULL,
`to` int(10) unsigned NOT NULL,
`country` char(2) NOT NULL,
PRIMARY KEY (`id`),
KEY `from` (`from`,`to`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Die Felder from und to beinhalten die IP-Adresse als long integer (also kein dotted quad) und werden gemeinsam indiziert. Im Feld country wird der Ländercode im ISO3166-Format gespeichert.
Mit einer kleinen PHP-Funktion lese ich die CSV-Datei in die Datenbank ein:
function ip2country_csv($filename)
{
$array = file($filename);
foreach ($array as $row)
{
if (preg_match('/^"([0-9]{1,10})","([0-9]{1,10})",'
. '"([A-Z]{2})".+$/', $row, $tmp))
{
mysql_query("INSERT INTO
`ip_locations`
SET
`from` = '{$tmp[1]}',
`to` = '{$tmp[2]}',
`country` = '{$tmp[3]}'");
}
}
}
Jetzt kann ich mit einer einfachen MySQL-Anfrage das Land ermitteln:
SELECT
`country`
FROM
`ip_locations`
WHERE
<IP> BETWEEN `from` AND `to`;
Natürlich muss man <IP> vorher durch die gesuchte IP-Adresse ersetzen. Diese kann man mit der PHP-Funktion ip2long() leicht von dottet quad in long integer umwandeln.
Angenommen ich hätte eine Session-Tabelle, die die IP-Adresse als long integer beinhaltet. Dann könnte ich wie folgt effizient das Land ermitteln:
SELECT
`sessions`.*
FROM
`sessions` LEFT OUTER JOIN `ip_locations` ON `sessions`.`ip`
BETWEEN `ip_locations`.`from` AND `ip_locations`.`to`;
Das sollte für’s Erste reichen. Man kann diese Angaben dann mit einer Flaggen-Bild-Bibliothek noch schön erweitern, so dass man in einer Tabelle die Landesflagge ausgeben kann.
PS: Mir geht an WordPress ziemlich auf die Nerven, dass es meine Leerzeichen in den Code-Abschnitten beim Speichern verschluckt. Wenn jemand ein praktisches Plugin kennt, was mir bei dieser Sache hilft, wäre ich sehr froh.