IP4 Adressen mit PHP und MySQL

IP-Adressen vergleichen

Meist werden IP4-Adressen vermutlich in einem VARCHAR(15) Feld gespeichert in einer Datenbank gespeichert.
Man kann die IP-Adresse auch in einem INT Feld speichern. Dazu muss sie zuvor in das Format Long übertragen werden. In PHP übernimmt diese Aufgabe die Funktion ip2long(), in MySQL lautet die entsprechende Anweisung INET_ATON(). Der umgekehrte Weg funktioniert natürlich auch, sonst würde das ganze wenig sinnvoll sein, die PHP Funktionen long2ip(), bzw. INET_NTOA() in MySQL erledigen diese Aufgabe.

Das Prinzip dahinter ist recht simple, eine IP4 Adresse besteht aus vier jeweils durch einen Punkt getrennten Blöcken. Jeder einzelne Block hat eine Größe von einem Bye also als Dezimalzahl einen Bereich von 0 bis 255.

IP Adresse    130.094.122.195  10000010 1011110 1111010 11000011  ip-adresse

IP-Adresse: 130.094.122.195
IP in Hex: 0×28.0×5E.0×7A.0×C3
Punkte entfernen: 0xC0A8FE01
Dezimal: 3232300545

Die Rückumwandlung geschieht entsprechend, erst die Long-Dezimalzahl wieder in Hex umwandeln, die Punkte zwischen die einzelnen Bytes setzen und dann kann man das ganze wieder in Dezimalwerte übertragen.

Wozu das Ganze? Vordergründig kann man so Platz sparen, ein VARCHAR(15) verbraucht 16 Bytes, ein 4-Byte-Long eben nur 4 Bytes. Man reduziert den benötigten Speicherplatz auf ein Drittel. Zwar ist Speicherplatz heute kein wirkliches Problem mehr, aber, wenn man bei großen Projekten Millionen von IP-Adressen protokollieren will, dann macht sich die Ersparnis schnell bemerkbar.
Außerdem ist eine MySQL-Datenbank umso langsamer, je größer die zu betrachtenden Datenmengen sind.

Der andere Zweck der Übung ist jedoch, dass man auf diese Weise leicht IP-Adressen vergleichen kann. Hat man zum Beispiel eine Datenbank, in der IP-Ranges für bestimmte geographische Regionen hinterlegt sind, möchte man unter Umständen wissen, aus welcher Region der Aufrufer einer Website kommt, beispielsweise um lokale Nachrichten einzublenden oder ähnliches.
Dazu muss man die IP-Bereiche nicht einmal als Long gespeichert haben, wie unten stehendes Beispiel zeigt:

SELECT country
FROM   geo_ip
WHERE  INET_ATON(’130.094.122.195′) >= INET_ATON(ip_range_begin)
AND    INET_ATON(’130.094.122.195′) <= INET_ATON(ip_range_end)

Dieses Statement würde also das jeweilige Land zurückliefern, aus dem heraus der Aufruf der Website erfolgt ist. Dazu braucht es in diesem Fall noch nicht einmal PHP-Code, die gesamte Logik kann im SQL-Statement untergebracht werden.


You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

AddThis Social Bookmark Button

Leave a Reply


Comments links could be nofollow free.


Amazon Bookshop