long2ip php sql mysql database ip-address

php - long2ip()



INET_ATON() e INET_NTOA() en PHP? (6)

Aquí funciones alternativas de PHP (copiar / pegar simples en su programa) -

function inet_aton($ip) { $ip = trim($ip); if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) return 0; return sprintf("%u", ip2long($ip)); } function inet_ntoa($num) { $num = trim($num); if ($num == "0") return "0.0.0.0"; return long2ip(-(4294967295 - ($num - 1))); }

Quiero almacenar direcciones IP en mi base de datos, pero también necesito usarlas en mi aplicación. Leí acerca de usar INET_ATON() e INET_NTOA() en mis consultas MySQL para obtener un entero sin signo de 32 bits de una dirección IP, que es exactamente lo que quiero, ya que hará que la búsqueda en la base de datos sea más rápida que con char (15) .

La cuestión es que no puedo encontrar una función que haga el mismo tipo de cosas en PHP. Lo único que encontré es:

http://php.net/manual/en/function.ip2long.php

Entonces lo probé:

$ip = $_SERVER[''REMOTE_ADDR'']; echo ip2long($ip);

Y no produce nada. En el ejemplo que dieron parece que funciona, pero no estoy seguro si ip2long() hace lo mismo que INET_ATON() .

¿Alguien sabe una función PHP que hará esto? ¿O incluso una solución completamente nueva para almacenar una dirección IP en una base de datos?

Gracias.


Hay una distinción importante entre ip2long , long2ip y las funciones de MySQL.

PHP ip2long y long2ip ocupan de enteros con signo.

Ver http://php.net/manual/en/function.ip2long.php

"Como el tipo entero de PHP está firmado, y muchas direcciones IP darán como resultado números enteros negativos en las arquitecturas de 32 bits, debe usar el formateador ''% u'' de sprintf () o printf () para obtener la representación de cadena de la IP sin firmar dirección."

INET_ATON() INET_NTOA() e INET_NTOA() tratan con enteros sin signo

Ver http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_inet-aton

"Para almacenar los valores generados por INET_ATON (), use una columna INT UNSIGNED en lugar de INT, que está firmada. Si usa una columna con signo, los valores correspondientes a las direcciones IP para las cuales el primer octeto es mayor que 127 no pueden almacenarse correctamente".

Aquí hay algunas funciones que puede usar para trabajar entre los dos.

Si insertaste en la base de datos MySQL, una IP usando INET_ATON() , puedes convertirla nuevamente en PHP usando lo siguiente:

long2ip(sprintf("%d", $ip_address));

Y puede convertirlo para guardarlo en la base de datos desde PHP usando esto:

sprintf("%u", ip2long($ip_address));

(También es importante que no escriba " $ip_address en " int ya que esto podría causar problemas al envolver el número si es mayor que MAX_INT . Si debe convertirlo, MAX_INT long o float )


Las ip2long() y long2ip() deberían funcionar bien.

Nota: debe usarlos para las direcciones IPv4; asegúrese de que, en su caso, $_SERVER[''REMOTE_ADDR''] realidad contenga una dirección IPv4 válida (y no algunas cosas de IPv6) .


Probando una dirección de IP de Google:

var_dump(ip2long(''209.85.227.147'')); var_dump(long2ip(3512066963));

Obtengo el siguiente resultado:

int(3512066963) string(14) "209.85.227.147"


No debería tener que lidiar con eso dentro de PHP, para eso están las funciones nativas de MySQL. Mira este ejemplo:

create table iptable ( ip int(32) unsigned not null, comment varchar(32) not null ); insert into iptable (ip, comment) values (inet_aton(''10.0.0.3''), ''This is 10.0.0.3''); select * from iptable; +-----------+------------------+ | ip | comment | +-----------+------------------+ | 167772163 | This is 10.0.0.3 | +-----------+------------------+ select inet_ntoa(ip) as ip, comment from iptable; +----------+------------------+ | ip | comment | +----------+------------------+ | 10.0.0.3 | This is 10.0.0.3 | +----------+------------------+

Si desea tratar tanto con ipv4 como con ipv6 en el mismo campo y está utilizando Mysql 5.6 o superior, puede usar varbinary (16) y las funciones inet6_aton e inet6_ntoa. Este es un mejor ejemplo de por qué debería usar funciones de MySQL y no tratar con datos binarios dentro de PHP:

create table iptable2 ( ip varbinary(16) not null, comment varchar(32) not null ); insert into iptable2 (ip, comment) values (inet6_aton(''192.168.1.254''), ''This is router 192.168.1.254''), (inet6_aton(''::1''), ''This is ipv6 localhost ::1''), (inet6_aton(''FE80:0000:0000:0000:0202:B3FF:FE1E:8329''), ''This is some large ipv6 example'') ; select * from iptable2; +------------------+---------------------------------+ | ip | comment | +------------------+---------------------------------+ | +¿?¦ | This is router 192.168.1.254 | | ? | This is ipv6 localhost ::1 | | ¦Ç ??¦ ¦?â) | This is some large ipv6 example | +------------------+---------------------------------+ select inet6_ntoa(ip) as ip, comment from iptable2; +--------------------------+---------------------------------+ | ip | comment | +--------------------------+---------------------------------+ | 192.168.1.254 | This is router 192.168.1.254 | | ::1 | This is ipv6 localhost ::1 | | fe80::202:b3ff:fe1e:8329 | This is some large ipv6 example | +--------------------------+---------------------------------+

Puede ver que al hacer esto, puede evitar tener que evaluar direcciones IPv6 en diferentes formatos, ya que MySQL los convierte en binarios y vuelve a su expresión más simple.

Sé que esta pregunta ya lleva más de 2 años, pero quiero que esta información sea útil para otros que se encuentran.

HTH

Francisco Zarabozo


Para la compatibilidad con IPv4 e IPv6, use inet_pton() y inet_ntop() , estos están disponibles desde PHP 5.1+ e imitan exactamente las funciones equivalentes de MySQL.

De lo contrario, solo use ip2long() y long2ip() .


ip2long es equivalente a inet_aton ().

ip2long solo funciona con IPv4. Sospecho que su sistema está usando IPv6 para loopback. Intenta imprimir REMOTE_ADDR.