Обнаружение IPv6-адреса в PHP и правильное его хранение в MySQL.Как? - PullRequest
4 голосов
/ 05 июня 2011

Я прочитал несколько вопросов, которые уже задавались, и нашел это полезным, хотя я не пробовал Работа с адресами IPv6 в PHP

Тем не менее, скажем, у меня есть таблица «запретов» в MySQL. Как мне сохранить адрес IPv6? Метод должен быть универсальным, т. Е. Поле должно содержать адрес ipv4 или ipv6. Это также должно относиться к моему полю ip_addr в моей таблице пользователей.

я бы обычно проверял if(getip == $bans['ip']) { do something } Но моя функция getip предназначена для ipv4 afaik, и мне интересно, будет ли она работать.

Я использую функцию

function getip()
{
    if(isset($_SERVER['REMOTE_ADDR']))
    {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
    {
    if(preg_match_all("#[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}#s", $_SERVER['HTTP_X_FORWARDED_FOR'], $addresses))
    {
        foreach($addresses[0] as $key => $val)
        {
            if(!preg_match("#^(10|172\.16|192\.168)\.#", $val))
            {
                $ip = $val;
                break;
            }
        }
    }
}

if(!isset($ip))
{
    if(isset($_SERVER['HTTP_CLIENT_IP']))
    {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    }
    else
    {
        $ip = '';
    }
}

$ip = preg_replace("#([^.0-9 ]*)#", "", $ip);
return $ip;
}

Ответы [ 2 ]

9 голосов
/ 17 сентября 2011

Я искал лучший тип данных в mysql, чтобы использовать для хранения адреса ipv6 недавно.Я не нашел веской причины использовать VARCHAR (), только веские причины NOT to.

Я провел некоторое тестирование производительности с данными BINARY (16), двумя BIGINT UNSIGNED и DECIMAL.типы.

Я создал следующие таблицы, заполненные 2 000 000 случайных IP-адресов из 100 случайных сетей.

CREATE TABLE ipv6_address_binary (
    id SERIAL NOT NULL AUTO_INCREMENT PRIMARY KEY,
    addr BINARY(16) NOT NULL UNIQUE
);

CREATE TABLE ipv6_address_twobigints (
    id SERIAL NOT NULL AUTO_INCREMENT PRIMARY KEY,
    haddr BIGINT UNSIGNED NOT NULL,
    laddr BIGINT UNSIGNED NOT NULL,
    UNIQUE uidx (haddr, laddr)
);

CREATE TABLE ipv6_address_decimal (
    id SERIAL NOT NULL AUTO_INCREMENT PRIMARY KEY,
    addr DECIMAL(39,0) NOT NULL UNIQUE
);

Затем я выбираю все IP-адреса для каждой сети и записываю время отклика.,Среднее время отклика для таблицы с двумя значениями составляет около 1 секунды, в то время как для двоичной таблицы оно составляет примерно одну сотую секунды.

Вот запросы.

Примечание:

X_ [HIGH / LOW] является наиболее / наименее значимым 64-разрядным битом X

, когда NETMASK_LOW равен 0, условие AND опускается, поскольку оно всегда возвращает true.не сильно влияет на производительность.

SELECT COUNT(*) FROM ipv6_address_twobigints
WHERE haddr & NETMASK_HIGH = NETWORK_HIGH
AND laddr & NETMASK_LOW = NETWORK_LOW

SELECT COUNT(*) FROM ipv6_address_binary
WHERE addr >= NETWORK
AND addr <= BROADCAST

SELECT COUNT(*) FROM ipv6_address_decimal
WHERE addr >= NETWORK
AND addr <= BROADCAST

Среднее время ответа:

Average response times

BINARY_InnoDB  0.0119529819489
BINARY_MyISAM  0.0139244818687
DECIMAL_InnoDB 0.017379629612
DECIMAL_MyISAM 0.0179929423332
BIGINT_InnoDB  0.782350552082
BIGINT_MyISAM  1.07809265852
0 голосов
/ 05 июня 2011

Тем не менее, скажем, у меня есть таблица "запретов" в MySQL. Как мне сохранить адрес IPv6?

Вы можете хранить его в простом столбце VARCHAR (40).
Учитывая пример IPv6, максимальный размер составляет 40 байт:

2001:0DB8:0000:0000:0000:0000:1428:57ab 

Этот кулмн также может содержать IPv4

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...