Функция PHP inet_ntop(): всё, что нужно знать
Функция inet_ntop() преобразует упакованный двоичный IP-адрес в удобочитаемую строку. Узнайте, как работать с IPv4 и IPv6 в PHP.
Функция inet_ntop() преобразует упакованный двоичный IP-адрес в удобочитаемую строку. Название расшифровывается как «network to presentation» («сеть → представление»): она берёт компактную форму IP-адреса фиксированной длины, хранящуюся в памяти (или в столбце базы данных), и возвращает её в привычную запись с точками (127.0.0.1) или с двоеточиями в шестнадцатеричном формате (::1), которую легко читать и записывать в журналы.
На этой странице объясняется, что представляет собой упакованный формат, как использовать inet_ntop() для IPv4 и IPv6, как она работает в паре с inet_pton(), как обрабатывать ошибки и когда стоит её применять.
Почему существует «упакованный» формат
IPv4-адрес вроде 192.168.1.1 — это всего 32 бита, то есть четыре байта. IPv6-адрес занимает 128 бит — шестнадцать байт. Привычная текстовая запись является лишь представлением этих байт, а не самими байтами.
Когда адреса хранятся или сравниваются в большом количестве, необработанные байты занимают меньше места и обрабатываются быстрее: столбец VARBINARY(16) вмещает любой IPv4- или IPv6-адрес, правильно сортируется и хорошо индексируется. inet_pton() создаёт упакованное представление, а inet_ntop() выполняет обратное преобразование, возвращая удобочитаемую строку.
"127.0.0.1" --inet_pton()--> \x7f\x00\x00\x01 (4 packed bytes)
\x7f\x00\x00\x01 --inet_ntop()--> "127.0.0.1" (readable text)Синтаксис
inet_ntop(string $ip): string|falseФункция принимает один параметр:
$ip— двоичная строка, содержащая упакованный IP-адрес. Длина должна быть ровно 4 байта для IPv4 или 16 байт для IPv6.
Функция возвращает адрес в виде удобочитаемой строки или false, если входные данные не являются корректным упакованным адресом длиной 4 или 16 байт.
Преобразование IPv4-адреса
Упакованный IPv4-адрес — это четыре необработанных байта, по одному на октет. Адрес обратной петли 127.0.0.1 представлен байтами \x7f (127), \x00, \x00, \x01:
Записывать управляющие последовательности вручную — ненадёжно. На практике упакованные байты получают из inet_pton() или из базы данных, а затем передают напрямую в inet_ntop():
<?php
$packed = inet_pton("192.168.1.1"); // text -> 4 packed bytes
echo inet_ntop($packed); // Outputs: 192.168.1.1Преобразование IPv6-адреса
Та же функция работает и с IPv6 — передайте ей 16-байтную упакованную строку, и она вернёт сжатую форму с двоеточиями в шестнадцатеричном формате, автоматически заменяя последовательности нулей на :::
<?php
$packed = inet_pton("2001:db8::1");
echo inet_ntop($packed); // Outputs: 2001:db8::1Так как одна функция поддерживает оба семейства адресов, можно выполнять обратное преобразование любого адреса без ветвления по типу — это удобно, когда столбец может содержать адреса обоих видов.
Обработка некорректных входных данных
Если двоичная строка имеет длину не 4 и не 16 байт, inet_ntop() возвращает false и выдаёт предупреждение. Всегда проверяйте результат перед использованием:
<?php
$result = inet_ntop("not a packed address");
if ($result === false) {
echo "Invalid packed address.";
} else {
echo $result;
}
// Outputs: Invalid packed address.Используйте строгое сравнение === false: нестрогая проверка также отвергла бы "0.0.0.0", который является допустимым адресом.
inet_ntop() и ip2long()
Для IPv4 можно также встретить long2ip(), который преобразует 32-битное целое число обратно в строку с точками. Разница между ними:
ip2long()/long2ip()работают с целочисленным представлением и поддерживают только IPv4.inet_pton()/inet_ntop()работают с двоичной строкой и поддерживают IPv4 и IPv6.
Если приложение должно обрабатывать IPv6, предпочтительнее использовать пару inet_*, чтобы один путь кода обслуживал любые адреса.
Когда применять
- Чтение адресов из хранилища — столбец
VARBINARY(16)компактно хранит любой адрес;inet_ntop()преобразует строки для отображения или записи в журнал. - Нормализация пользовательского ввода — преобразование через
inet_pton()и затемinet_ntop()даёт каноническую форму (например,2001:0db8::0001становится2001:db8::1), поэтому равные адреса сравниваются как равные строки. - Работа с необработанными данными сокетов — упакованные адреса, возвращаемые низкоуровневыми сетевыми вызовами, становятся удобочитаемыми для журналов и сообщений об ошибках.
Связанные функции
inet_pton()— обратная операция: удобочитаемый адрес в упакованную двоичную строку.ip2long()— строка IPv4 в целое число.long2ip()— целое число обратно в строку IPv4.gethostbyname()— разрешение имени хоста в его IPv4-адрес.
Заключение
inet_ntop() преобразует упакованный 4- или 16-байтный IP-адрес обратно в удобочитаемый текст для IPv4 и IPv6, дополняя inet_pton(). Храните адреса в компактном двоичном формате для эффективной индексации, преобразуйте их с помощью inet_ntop(), когда нужно отобразить или записать их в журнал, и всегда проверяйте возврат false при некорректных входных данных.