Никто не опубликовал полный рабочий ответ (и во многих примерах используется Windows ::1
, которая может быть очень вводящей в заблуждение для живых (или "производственных") сред) где угодно (по крайней мере, я можно найти) так вот:
- Формат для хранения.
- Пример
INSERT
запроса с использованием достаточно сложного IP-адреса IPv6.
- Пример
SELECT
запроса о том, что вы сможете echo
вернуть IP-адрес IPv6 клиенту.
- Устранение неполадок, чтобы вы не пропустили ни один устаревший код.
Я изменил все имена столбцов на ipv6
, чтобы отразить, что они должным образом поддерживают IPv6 (и это позволяет сохранить старый столбец ip
без изменений). Можно сохранить столбец ip
в столбце ipv6
, а затем просто DROP
столбец ip
, если вы уверены, что преобразование сработало; когда у меня действительно будет время, я добавлю это к этому сообщению.
Тип данных IPv6
Как уже упоминалось, VARBINARY 16
- желательный путь, пока AMD не благословит нас 128-битными процессорами, а базы данных не будут обновлены для поддержки 128-битных целых чисел (я правильно сказал?). IPv6 128-битный, а не 64-битный.
CREATE TABLE `example`
(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`ipv6` VARBINARY(16) NOT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8mb4_unicode_520_ci'
ENGINE=InnoDB;
Запрос вставки IPv6
Очевидно, нам нужно сохранить IPv6-адрес, прежде чем мы сможем SELECT
его; вот код PHP / SQL :
$ipv6 = mysqli_real_escape_string($db,'FE80:0000:0000:0000:0202:B3FF:FE1E:8329');
$query1 = "INSERT INTO example (ipv6) VALUES (INET6_ATON('$ipv6'));";
IPv6 SELECT Query
Код PHP / SQL :
$ipv6 = mysqli_real_escape_string($db,'FE80:0000:0000:0000:0202:B3FF:FE1E:8329');
$query2 = "SELECT INET6_NTOA(ipv6) AS ipv6 FROM example WHERE ipv6=INET6_ATON('$ipv6');";
Это вернет fe80::202:b3ff:fe1e:8329
; нет, не полный IPv6 (то есть FE80:0000:0000:0000:0202:B3FF:FE1E:8329
), это сжатая / сокращенная версия. Есть код, делающий его официальной полноформатной версией, но это для того, чтобы сэкономить время для себя и других, потому что этот Q / A - это то, что продолжает появляться.
Важно: только потому, что некоторые IPv6-адреса выглядят , как будто они вписываются в bigint
, не не , подразумевают две минуты позже кто-то с большим IPv6-адресом не сможет зайти и нанести ущерб.
Надеюсь, это спасет некоторых людей от безумия, открыв еще две дюжины вкладок. Когда у меня будет время в будущем, я добавлю дополнительный код PHP, который расширяет сжатый IPv6 до полного формального формата.
Поиск и устранение неисправностей
Если по какой-то причине сохранение и / или получение адресов IPv6 не работает, возьмите себе копию Advanced Find and Replace (работает в Wine быстрее, чем встроенная в Linux grep
); используйте это преимущественно для поиска, а не замены. Убедитесь, что ваш код соответствует везде в вашем программном обеспечении.
- Все
$ip
переменные должны быть преобразованы в $ipv6
, чтобы вы знали, что этот бит покрыт.
- Не забудьте удалить окончание
)
для следующих четырех шагов:
- Поиск всех экземпляров функций PHP
inet_pton(
и их удаление.
- Поиск всех экземпляров функций PHP
inet_ntop(
и удаление их.
- Поиск всех экземпляров функций SQL
INET_ATON(
и удаление их.
- Поиск всех экземпляров функций SQL
INET_NTOA(
и удаление их.
- Найдите все экземпляры
$ipv6
и убедитесь, что все экземпляры IP-IN-TO-SQL используют INET6_ATON('$ipv6')
и что все экземпляры, где IP-FROM-SQL используют INET6_NTOA(ipv6) AS ipv6
.
- Поиск всех экземпляров
$row1['ip']
и замена их на $row1['ipv6']
.
- Убедитесь, что все экземпляры
$ipv6 =
используют следующий код (с измененной ссылкой на объект базы данных): $ipv6 = (isset($_SERVER['REMOTE_ADDR']) && strlen($_SERVER['REMOTE_ADDR']) > 0) ? mysqli_real_escape_string($db,$_SERVER['REMOTE_ADDR']) : mysqli_real_escape_string($db,getenv('REMOTE_ADDR'));
.
- Убедитесь, что в ваших тестах используются недавно протестированных IP-адресов вместо потенциально испорченных версий, если вы знаете, что что-то не так до , когда вы начали отладку.