ip2nation, sans base de données

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

04 août 2007, 21:18

Attisé par ce sujet, j'ai voulu voir s'il était possible de se passer de base de données pour utiliser les données de ip2nation

Je vous donne le prototype final, très peu testé et pas du tout documenté, au cas où cela serve à quelqu'un un jour. Se passer de base de données reste une mauvaise idée, et je n'offre aucun support sur ce script, donc c'est entièrement à vos risques et périls !

Avant toute chose il faut avoir installé ip2nation sur une base de données et générer des fichiers (qui remplacent l'accès à la base). Le script qui s'occupe de ça est generate.php, n'oubliez pas de modifier la constante PATH_TO_IP2NATION ainsi que les infos pour accéder à la base. 256 fichiers contiennent les données de chaque classe d'IP et le 257ème contient le nom de chaque pays.

Le second script, contient la fonction qui sert à transformer une IP en code de pays (par exemple "fr") ou en nom de pays ("France"). Si l'IP n'est pas connue, la fonction renvoit false.

Ce fichier est domaine public et si quelqu'un me demande je nierai l'avoir créé, vous voilà prévenu !

generate.php
<?php

define('PATH_TO_IP2NATION', '/tmp/ip2nation');

$db = new mysqli('127.0.0.1', 'root', '', 'test');

$sql = '  SELECT code, country FROM ip2nationCountries';
$result = $db->query($sql);

$nations = array();
while ($row = $result->fetch_assoc())
{
	$nations[$row['code']] = $row['country'];
}
$result->close();

file_put_contents(PATH_TO_IP2NATION . '/data.nations.php', '<?php return unserialize(' . var_export(serialize($nations), true) . ');');

$sql = '  SELECT INET_NTOA(ip), country
		    FROM ip2nation
		ORDER BY ip';
$result = $db->query($sql);

$buf = '01';
$last_a = -1;

while ($row = $result->fetch_row())
{
	$p = explode('.', $row[0]);
	$a = $p[0];

	if ($a != $last_a)
	{
		if (isset($buf[2]))
		{
			file_put_contents(PATH_TO_IP2NATION . '/data/' . $last_a, $buf);
			$buf = substr($buf, -2);
		}

		$last_a = $a;
	}

	$buf .= chr($p[1]) . chr($p[2]) . chr($p[3]) . $row[1];
}
$result->close();

if (isset($buf[2]))
{
	file_put_contents(PATH_TO_IP2NATION . '/data/' . $last_a, $buf);
}
ip2nation.php
<?php

define('PATH_TO_IP2NATION', '/tmp/ip2nation');

function get_country($ip, $return_name = false)
{
	$p = explode('.', $ip);
	$a = $p[0];

	$filepath = PATH_TO_IP2NATION . '/data/' . $a;
	if (!file_exists($filepath))
	{
		return false;
	}

	$bcd = chr($p[1]) . chr($p[2]) . chr($p[3]);
	$data = file_get_contents($filepath);
	$len = strlen($data);

	for ($pos = 2; $pos < $len; $pos += 5)
	{
		if (strcmp(substr($data, $pos, 3), $bcd) > 0)
		{
			break;
		}
	}

	$code = substr($data, $pos - 2, 2);

	if ($return_name)
	{
		$nations = include(PATH_TO_IP2NATION . '/data.nations.php');
		return (isset($nations[$code])) ? $nations[$code] : $code;
	}

	return $code;
}

Mammouth du PHP | 558 Messages

04 août 2007, 21:57


Se passer de base de données reste une mauvaise idée[donc c'est possible?]

il faut avoir installé ip2nation sur une base de données[ça veut dire quoi?] et générer des
je n'ai rien compris car tu te contredit lol

Mammouth du PHP | 19672 Messages

04 août 2007, 22:41

Ben non il se contredit pas ; ce qu'il explique, c'est que les données sont actuellement disponibles sous la forme d'une base de données, pas de fichiers. Donc si tu veux travailler sur fichiers, il faut commencer par les générer... et à partir de quoi penses-tu pouvoir le faire sans la base au départ ? :-k
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe: