INET_ATON () ve inet_ntoa () PHP?

6 Cevap php

Benim veritabanında IP adreslerini saklamak istiyorum, ama benim de uygulama boyunca onları kullanmak gerekir. Ben üzerinden arama yapacak kadar istediğimi tam olarak ne olduğunu bir IP adresi, dışarı bir 32-bit işaretsiz tamsayı almak benim MySQL sorguları INET_ATON() ve INET_NTOA() kullanma hakkında okuyun char (15) kullanarak daha hızlı veritabanı.

Şey PHP şey aynı tür yapan bir işlevi bulamıyorum, olduğunu. Ben rastladım tek şey:

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

Yani bunu test:

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

Ve hiçbir şey çıktılar. Örnekte onlar iş gibi görünüyor verdi, ama sonra tekrar ip2long() INET_ATON() olarak aynı şeyi yaparsa tam olarak emin değilim.

Birisi bu yapacak bir PHP işlevini biliyor mu? Ya da bir veritabanında bir IP adresi saklamak için bile tamamen yeni bir çözüm?

Teşekkürler.

6 Cevap

ip2long() ve long2ip() fonksiyonlar sadece iyi çalışması gerekir.

Not: IPv4 için bu adresleri kullanmalısınız - emin olun, sizin durumda, $_SERVER['REMOTE_ADDR'] aslında geçerli bir IPv4 adresi (and not some IPv6-stuff) içerir.


Trying on a google IP address :

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

Ben şu çıktıyı alırsınız:

int(3512066963)
string(14) "209.85.227.147" 

Ip2long, long2ip ve MySQL fonksiyonları arasında önemli bir ayrım vardır.

Imzalanan tamsayılar ile PHP'nin ip2long ve long2ip anlaşma.

(See http://php.net/manual/en/function.ip2long.php "Because PHP's integer type is signed, and many IP addresses will result in negative integers on 32-bit architectures, you need to use the '%u' formatter of sprintf() or printf() to get the string representation of the unsigned IP address.")

Işaretsiz tamsayılar ile MySQL'in INET_ATON () ve inet_ntoa () anlaşma

(See http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_inet-aton "To store values generated by INET_ATON(), use an INT UNSIGNED column rather than INT, which is signed. If you use a signed column, values corresponding to IP addresses for which the first octet is greater than 127 cannot be stored correctly.")

Burada ikisi arasında çalışmak için kullanabileceğiniz bazı işlevler vardır.

Eğer MySQL veritabanı içine takılırsa, INET_ATON kullanarak bir IP (), aşağıdaki kullanarak PHP geri dönüştürebilirsiniz:

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

Ve sen bu kullanarak PHP veritabanında kaydetmek için dönüştürebilirsiniz:

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

(Ayrıca önemli, bu o MAX_INT daha büyük ise numarasını sararak sorunlara neden olabilir gibi int $ ip_address tip-döküm yok. Eğer döküm gerekiyorsa, bir uzun döküm veya float)

PHP içinde bu ile uğraşmak zorunda olmamalıdır, bu MySQL yerli funcions için var. Bu örneğe bakın:

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 |
+----------+------------------+

Eğer aynı alanda IPv4 hem de IPv6 ile başa çıkmak için, ve Mysql 5.6 veya üstü kullanıyorsanız istiyorsanız, varbinary (16) kullanabilir ve işlevleri inet6_aton ve inet6_ntoa. Bu PHP içinde ikili veri ile başa MySQL fonksiyonları kullanmak ve olmamalıdır neden daha iyi bir örnektir:

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 |
+--------------------------+---------------------------------+

Bunu yaparak, aslında MySQL onları geri simpliest ifade için ikili ve dönüştürür beri, farklı biçimlerde IPv6 adreslerini değerlendirmek zorunda önleyebilirsiniz görebilirsiniz.

Bu soru zaten daha 2 yıl var biliyorum, ama bu bilgiler rastlamak başkaları için yararlı olsun istiyorum.

HTH

Francisco Zarabozo

ip2long inet_aton () eşdeğerdir.

ip2long sadece IPv4 ile çalışır. Ben sistem geri döngü için IPv6 kullanıyor sanıyorum. REMOTE_ADDR yazdırmayı deneyin.

Burada PHP alternatif fonksiyonları (programa basit kopyala / yapıştır) -

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))); 
}