2016-08-07 5 views
-2

Ich habe 3000 Reihen von IP-Bereiche in diesem Format:PHP beste Möglichkeit, viele IP-Bereiche zu speichern?

5.9.0.0  5.9.255.255  Hetzner  http://www.hetzner.de/ 
5.10.64.0 5.10.127.255 SoftLayer http://www.softlayer.com/ 
5.34.182.0 5.34.183.255 UA Servers https://itldc.com/ 

Wenn ein Benutzer besucht meine Website ich Nachschlag wollen, wenn ihre IP in dieser IP-Bereiche und sie blockieren, wenn das der Fall ist. Was ist der schnellste Weg, um ihre IP mit PHP zu suchen? Die IP-Bereiche sind statisch und werden sich niemals ändern.

Ich dachte schon, eine .dat-Datei zu erstellen, um die IPs zu speichern, ist das ein guter Ansatz?

+0

postgresql unterstützt einen CIDR & INET Datentypen, nur fyi. Weiß nicht über mysql oder sqlite. – alzee

+1

Ich entfernte die inkompatiblen Datenbank-Tags. Bitte markieren Sie die Frage mit der von Ihnen verwendeten Datenbank oder erklären Sie explizit, warum sie ursprünglich sowohl mit MySQL als auch mit SQLite getaggt wurde. –

+0

Der schnellste Weg wäre eine In-Memory-Lösung (zwischen Prozessen geteilt) mit einer auf diese spezielle Anwendung zugeschnittenen Logik. Wahrscheinlich ein riesiger Overkill (und unnötige Arbeit) für Sie. Seien Sie ehrlich zu Ihren Anforderungen. –

Antwort

0

(Früher gab es eine link, wie die Aufgabe in PHP zu tun. Diese Frage zu MySQL zu sein scheint.)

Wenn Sie nur IPv4 tun, dann speichern Sie in Datentyp INT UNSIGNED und INET_ATON() verwenden beim Speichern und INET_NTOA() beim Abrufen. Verwenden Sie für IPv6 BINARY(16) mit INET6_ATON() und INET6_NTOA().

+0

Dies sollte ein Kommentar sein. –

0

Die Umwandlung des gepunkteten Quadrats in einen ganzzahligen Wert ist nur der Anfang einer Lösung.

Sie können Werte in einem Array oder aus einer Datenbank mit einem normalen Index nicht dereferenzieren. Betrachten Sie den Fall, in dem Sie einen Datensatz finden möchten, sagen Sie 125.54.123.8 in Ihren Bereichen. Wenn Ihre Bereiche mit der Startadresse verknüpft sind, können Sie nur Datensätze ausschließen, deren Startadresse größer als Ihr Suchwert ist. Wenn es am Ende des Bereichs eingegeben wird, können Sie nur Werte ausschließen, bei denen die Endadresse kleiner als Ihr Suchwert ist. Sie müssen immer noch ungefähr die Hälfte Ihrer Daten untersuchen, um eine Übereinstimmung zu finden (oder deren Fehlen).

Sie könnten Datenpakete oder verschachtelte Arrays verwenden, aber diese sind etwas kludgy Lösungen.

Eine weitere Verknüpfung ist, wenn Sie eine PHP-Datenstruktur verwenden, um die Bereiche zu verwalten ist die Zeit, die es dauert, den Datensatz zu laden und zu analysieren, bevor Sie mit der Suche beginnen können. Dieser Overhead tritt erfahrungsgemäß mit einem Datensatz von ca. 100-200 Zeilen auf, verglichen mit einem Datensatz von MySQL.

Die Lösung ist MySQL Geospatial-Funktionen abzubilden, die Bereiche in einem eindimensionalen Raum zu verwenden - ich Lookup-mal unter 1ms auf bescheidener Hardware Durchsuchen der gesamte Internet zugewiesenen Bereiche (mit den Datensätzen von RIPE, APNIC usw.) erhalten.

Das beschriebene Verfahren ist here

Hinweis: ip2long() gibt einen signierten 32-Bit-Integer-Wert in PHP, während MySQL INET_ATON,() ohne Vorzeichen ist (dh Sie can'tmix und passen die zwei Funktionen)

Verwandte Themen