Функция PHP inet_pton(): всё, что нужно знать
Функция inet_pton() в PHP преобразует IP-адрес из читаемого формата в упакованную двоичную строку. Поддерживает IPv4 и IPv6.
Функция PHP inet_pton() преобразует IP-адрес в читаемом виде — например, 127.0.0.1 или 2001:db8::1 — в его упакованное двоичное представление. Название расшифровывается как «presentation to network» («представление в сетевой формат»): функция принимает представление (текст с точками или двоеточиями, который вы вводите) и возвращает сетевую форму (сырые байты, которые реально передаются по сети).
На этой странице рассматриваются синтаксис, работа с IPv4 и IPv6, безопасное чтение результата, обратное преобразование и практические причины хранить IP-адреса в двоичном виде.
Что такое функция inet_pton()?
inet_pton() разбирает корректную строку IPv4 или IPv6 и возвращает упакованную двоичную строку — 4 байта для IPv4 и 16 байт для IPv6. Если входные данные не являются допустимым IP-адресом, функция возвращает false вместо того, чтобы выбросить исключение.
Возвращаемая «двоичная строка» не является читаемой для человека: это сырые байты, поэтому при прямом выводе в терминал или браузер вы увидите нечитаемые символы. Чтобы просмотреть её содержимое, преобразуйте её с помощью bin2hex(). Чтобы вернуть её обратно в обычную строку IP-адреса, используйте зеркальную функцию inet_ntop().
Синтаксис
inet_pton(string $ip): string|falseФункция принимает один параметр:
$ip— IP-адрес для преобразования в виде строки (IPv4 или IPv6).
Возвращаемое значение: упакованная двоичная строка при успехе или false, если $ip не является допустимым IP-адресом.
Базовый пример: IPv4
Сырые 4 байта адреса 127.0.0.1 — это 7f 00 00 01, то есть десятичные октеты 127.0.0.1, записанные в шестнадцатеричном виде. Поскольку двоичная строка сама по себе не является печатаемой, мы пропускаем её через bin2hex(), чтобы байты отображались в виде читаемого шестнадцатеричного числа.
IPv4 и IPv6
В отличие от устаревшей функции ip2long(), которая работает только с IPv4, inet_pton() поддерживает оба семейства адресов. IPv4 даёт 4 байта, IPv6 — 16:
<?php
echo bin2hex(inet_pton("192.168.1.1")), "\n"; // c0a80101 (4 bytes)
echo bin2hex(inet_pton("2001:db8::1")), "\n"; // 20010db8000000000000000000000001 (16 bytes)
echo strlen(inet_pton("192.168.1.1")), "\n"; // 4
echo strlen(inet_pton("2001:db8::1")), "\n"; // 16Проверка strlen() на результате — самый простой способ определить семейство адресов: длина 4 означает IPv4, 16 — IPv6.
Обработка некорректных входных данных
Если строка не является допустимым IP-адресом, inet_pton() возвращает false. Всегда проверяйте результат перед его использованием — иначе вы можете случайно сохранить или сравнить false (пустую строку):
<?php
$input = "not-an-ip";
$packed = inet_pton($input);
if ($packed === false) {
echo "Invalid IP address";
} else {
echo bin2hex($packed);
}
// Outputs: Invalid IP addressИспользуйте строгое сравнение (===). Допустимый адрес 0.0.0.0 упаковывается в байты 00000000, первый из которых является нулевым байтом; нестрогая проверка == false может дать ложный результат в граничных случаях, поэтому === false является надёжным способом проверки.
Обратное преобразование
inet_pton() и inet_ntop() — это пара взаимодополняющих функций: одна упаковывает, другая распаковывает. При последовательном применении возвращается исходный адрес:
<?php
$packed = inet_pton("2001:db8::1");
echo inet_ntop($packed); // Outputs 2001:db8::1Когда это использовать?
Хранение IP-адресов в упакованном двоичном виде прежде всего обеспечивает компактное, сортируемое, независимое от семейства адресов хранение:
- Хранение в базе данных. Бинарный столбец (
VARBINARY(16)) хранит любой адрес IPv4 или IPv6 в фиксированном компактном виде и сортируется корректно. Используйтеinet_pton()передINSERTиinet_ntop()послеSELECT. - Сравнение диапазонов. Поскольку байты сохраняют числовой порядок, можно сравнивать упакованные строки, чтобы проверить, входит ли адрес в подсеть.
- Поиск точного совпадения. Сравнение ключей фиксированной длины в двоичном виде выполняется быстрее и устраняет неоднозначность текстовых форм (например,
2001:db8::1и2001:0db8:0000:...:0001— это один и тот же адрес, но разные строки; упаковка нормализует их).
Для числовой арифметики только с IPv4 альтернативой служат ip2long() и long2ip(), однако они не поддерживают IPv6.
Заключение
inet_pton() преобразует IPv4 или IPv6 адрес из читаемой текстовой формы в упакованную двоичную строку — 4 байта для IPv4 и 16 для IPv6 — и возвращает false при некорректных входных данных. Используйте её в паре с inet_ntop() для обратного преобразования и bin2hex(), если нужно просмотреть сырые байты. Это стандартный способ компактного хранения и сравнения IP-адресов в базе данных с поддержкой обоих семейств адресов.