2011-02-27 3 views
80

Possible en double:
How to store an IP in mySQLQuel type de données MySQL utiliser pour une adresse IP?

Je veux obtenir l'adresse IP de $_SERVER['REMOTE_ADDR'] et d'autres $_SERVER variables, qui est le type de données de droite pour cela?

Est-ce VARCHAR(n)?

+0

Voir ce ([discussion] http://forums.mysql.com/read. php? 21,49094,49094 # msg-49094) – Ragnar123

+8

Je ne suis pas d'accord qu'il s'agit d'une question en double, puisque l'autre question est spécifiquement une question liée à la performance pour stocker un très grand nombre d'adresses IP. La réponse à cette question peut ne pas être pertinente pour quelqu'un qui n'est pas intéressé par la maximisation de l'utilisation de l'espace ou de la performance. – User

+0

@User J'ai posé cette question il y a environ un an et demi;) Mais merci de partager votre opinion. – ComFreek

Répondre

123

Puisque les adresses IPv4 sont 4 octets de long, vous pouvez utiliser une INT (UNSIGNED) qui a exactement 4 octets:

`ipv4` INT UNSIGNED 

et INET_ATON et INET_NTOA pour les convertir:

INSERT INTO `table` (`ipv4`) VALUES (INET_ATON("127.0.0.1")); 
SELECT INET_NTOA(`ipv4`) FROM `table`; 

Pour IPv6, vous pouvez utiliser un adresses BINARY à la place:

`ipv6` BINARY(16) 

Et utiliser PHP’s inet_pton et inet_ntop pour la conversion:

'INSERT INTO `table` (`ipv6`) VALUES ("'.mysqli_real_escape_string(inet_pton('2001:4860:a005::68')).'")' 
'SELECT `ipv6` FROM `table`' 
$ipv6 = inet_pton($row['ipv6']); 
+5

La syntaxe pour 5.1 est INT UNSIGNED, non UNSIGNED INT –

+0

Avec la méthode suggérée - Comment trouver des adresses avec un sous-réseau correspondant? –

+1

@AlexanderFarber [Vérifie si l'adresse IP est dans le sous-réseau] (http://stackoverflow.com/a/10002060/53114) – Gumbo

39

Vous avez deux possibilités (pour une adresse IPv4):

  • un varchar(15), si votre voulez stocker l'adresse IP en tant que chaîne
    • 192.128.0.15 par exemple
  • et integer (4 octets), si vous convertissez l'adresse IP à un nombre entier
    • 3229614095 pour l'IP je avant


La deuxième solution nécessite moins d'espace dans la base de données, et est probablement un meilleur choix, même si cela implique un peu des manipulations lors du stockage et de la récupération des données (conversion de/vers une chaîne).

A propos de ces manipulations, voir les fonctions ip2long() et long2ip(), sur le côté PHP, ou inet_aton() et inet_ntoa() sur le côté MySQL.

+0

Mais j'ai entendu dire que cela peut aussi être une adresse IPv6 dans $ _SERVER ['REMOTE_ADDR']. Et comment puis-je convertir quelque chose comme xxx.xx.xx.xxx en un entier (4 octets) comme vous l'avez dit? – ComFreek

+1

Pour une adresse IPv6, vous aurez besoin de plus de 4 octets - https://secure.wikimedia.org/wikipedia/en/wiki/IPv6 indique qu'il utilise 128 bits, donc 16 octets ;; en PHP, voir http://fr2.php.net/manual/en/function.inet-pton.php –

+0

Quel type de données serait correct pour 16 octets? – ComFreek

5

Pour les adresses IPv4, vous pouvez utiliser VARCHAR pour les stocker en tant que chaînes, mais également pour les stocker sous forme d'entiers longs INT(11) UNSIGNED. Vous pouvez utiliser la fonction INET_ATON() de MySQL pour les convertir en représentation entière.L'avantage est qu'il vous permet de faire des comparaisons faciles sur eux, comme BETWEEN interroge

INET_ATON() MySQL function

Questions connexes