Standart Internet Formatı

Çoğu kişiye göre IP adreslerini veritabanı tablolarında karakter dizisi (string) olarak depolamak oldukça kolaydır. İlgili tabloda VARCHAR (11) türünde bir alan oluşturulur ve 192.168.1.10 gibi IP adresleri kolayca anlaşılır bir şekilde depolanabilir.

Neden sayı olarak olmasın?

Aslında IP adresleri birer sayıdır ve çok daha efektif olarak depolanabilirler. Hatta PHP’de bu işlemi gerçekleştirmek için ip2long() adında bir fonksiyon bulunur ki IPv4 standard formattaki bir IP adresini bir sayıya (long integer) dönüştürür. Sonuç olarak, IP adresleri standart formata göre 1/3 oranında yer kaplar, sorgular ve indekslemeler hızlanır.
$ip='192.168.1.10';
echo ip2long($ip);

-1062731510 çıktısını verecektir.

Not: Çünkü PHP de tamsayılar negatif veya pozitif olabilir ve birçok IP adresi yukarıdaki örnekte olduğu gibi negatif sonuç döndürebilir.Bu sorunu çözmek için sprintf() veya printf() fonksiyonlarını “%u” parametresi kullanılarak pozitif tam sayılar elde edilebilir.

$ip='192.168.1.10';
echo ip2long($ip);
printf("%u\n", ip2long($ip));

3232235786 sonucunu verir ve bu değer MySQL’de INT(11) bir alanda depolabilir.

Süpriz bir şekilde 64bit Linux sistemlerde ip2long fonksiyonu negatif bir değer döndürmemektedir.Bunun nedenini araştırdığımda tam sayıların 64bit sistemlerde 32bit yerine 64bit olarak tutulması ve 32bitlerdeki 2147483647 sınırının bulunmaması olduğunu gördüm. Bu durumu 64bit Windows sistemlerde deneme fırsatım maalesef olmadı.

Ben yine de printf fonksiyon kullanımının uyumluluk açısından gerekli olduğunu düşünmekteyim.Zaten 64bit sistemlerde de bu fonksiyonun kullanımı herhangi bir sorun yaratmamakta.

Standart formata dönüştürme

long2ip() fonksiyonu yukarıda yapılan işlemin tersini gerçekleştirerek tam sayı (INT) olarak depolanmış IP adreslerini standart formata dönüştürür. Sayının pozitif veya negatif olması bir sorun teşkil etmez:

echo long2ip(ip2long($ip));
echo long2ip(sprintf("%u\n", ip2long($ip)));

Her iki komut da 192.168.1.10 çıktısını verir.

MySQL ile dönüştürme

Alternatif ve belki de en efektif yöntem bu işi MySQL’in INET_ATON() fonksiyonunu kullanarak MySQL’e yaptırmak olabilir:INSERT INTO `ip_addresses` INET_ATON('192.168.1.10'); will store 3232235786

Standart formatta verilen IP adresi tam sayı (3232235786) olarak tabloya kaydolacaktır.

Oluşan sayı daima ağ byte sıramasındadır. Örnekteki değer şu şekilde hesaplanmaktadır:

(192*256*256*256) + (168*256*256) + (1*256) + 10 = 3232235786

Standart IP adresine geri dönüştürme

Standart IP formatına geri dönüşüm için MySQL’in INET_NTOA() fonksiyonu kullanılabilir

SELECT INET_NTOA(3232235786);

192.168.1.10 sonucunu döndürür.

Yukarıda kullanılan iki fonksiyon MySQL 3.23.15 ve üstü versiyonlarda bulunmaktadır.