Функция PHP gethostbyaddr(): всё, что нужно знать
Узнайте, как работает функция PHP gethostbyaddr() для обратного DNS-поиска: синтаксис, возвращаемые значения и примеры использования.
Когда у вас есть IP-адрес и вы хотите узнать связанное с ним имя хоста, функция PHP gethostbyaddr() справится с этой задачей. Она выполняет обратный DNS-поиск — операцию, противоположную разрешению доменного имени в IP-адрес. В этой статье рассматриваются синтаксис, возвращаемые значения, распространённые сценарии использования и подводные камни, о которых стоит знать.
Что такое функция gethostbyaddr()?
gethostbyaddr() — встроенная функция PHP, выполняющая обратный DNS (rDNS) поиск для получения имени хоста, зарегистрированного за данным IP-адресом. Она использует системный DNS-резолвер, поэтому результат зависит от сети, в которой выполняется скрипт, а также от наличия у владельца IP настроенной PTR-записи.
Ключевые факты, которые нужно помнить:
- Принимает IPv4 или IPv6 адрес в виде string.
- При успешном поиске возвращает имя хоста в виде string.
- При неудачном поиске возвращает исходный string с IP-адресом без изменений — не
false. Это главная особенность поведения функции, которая влияет на то, как нужно проверять результат. - При некорректном аргументе (string, не являющийся валидным IP-адресом) возвращает
falseи генерирует предупреждение.
Обратный поиск завершится успешно только в том случае, если владелец IP-блока опубликовал PTR-запись. Для многих адресов (в том числе большинства домашних и многих облачных IP) PTR-запись отсутствует или не совпадает с прямой записью, поэтому «отсутствие» имени хоста — это норма, а не ошибка в вашем коде.
Синтаксис
gethostbyaddr(string $ip): string|false| Параметр | Тип | Описание |
|---|---|---|
$ip | string | IPv4 или IPv6 адрес для поиска. |
Возвращаемое значение: имя хоста при успехе, исходный string $ip, если имя хоста не найдено, или false, если $ip не является валидным адресом.
Базовый пример
Поскольку функция возвращает сам IP-адрес при неудаче разрешения, нужно сравнить результат с входными данными, чтобы обнаружить неудачу:
Здесь 8.8.8.8 (Google Public DNS) разрешается в имя хоста, например dns.google. Трёхсторонняя проверка различает некорректные входные данные (false), неразрешённый адрес (возвращает IP) и успешный поиск.
Получение имени хоста посетителя
Распространённый сценарий — логирование или аналитика: преобразование IP-адреса посетителя в читаемое имя хоста.
<?php
$ip = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
$host = gethostbyaddr($ip);
echo $host === $ip
? "Visitor IP $ip has no reverse DNS entry."
: "Visitor came from $host.";
?>Не используйте результат для контроля доступа. Обратный DNS может быть подделан тем, кто управляет PTR-записью данного IP-адреса, поэтому имя хоста вроде example.com само по себе ничего не доказывает. Для надёжного прямо-подтверждённого обратного DNS (FCrDNS) выполните поиск имени хоста с помощью gethostbyaddr(), а затем проверьте, что оно разрешается обратно в тот же IP с помощью gethostbyname().
Двусторонняя проверка с gethostbyname()
gethostbyaddr() и gethostbyname() — обратные функции друг для друга. Их можно использовать совместно, чтобы убедиться, что имя хоста и IP-адрес действительно совпадают:
<?php
$ip = "8.8.8.8";
$host = gethostbyaddr($ip);
$confirmed = gethostbyname($host) === $ip;
echo "Host: $host\n";
echo "Forward-confirmed: " . ($confirmed ? "yes" : "no") . "\n";
?>Когда $confirmed равно yes, оба направления DNS-поиска совпадают — это наибольшая степень уверенности, которую обычный DNS может дать в том, что имя хоста является легитимным.
Распространённые подводные камни
- Возвращённый IP — не ошибка. Всегда проверяйте
$result === $ip, а не считайте, что результат, не равныйfalse, является именем хоста. - Поиск медленный и блокирующий. Каждый вызов может ожидать сетевого ответа. Избегайте вызова функции в плотном цикле на каждый запрос; кешируйте результаты там, где это возможно.
- Сначала проверьте входные данные. Если значение может не быть валидным IP-адресом, прогоните его через
filter_var()с флагомFILTER_VALIDATE_IPперед вызовомgethostbyaddr(). - Результаты зависят от окружения. Один и тот же IP может возвращать разные имена хостов (или ни одного) в зависимости от DNS-серверов, настроенных в среде выполнения скрипта.
Связанные функции
gethostbyname()— разрешение имени хоста в IPv4-адрес (прямой поиск).gethostbynamel()— получение полного списка IPv4-адресов для имени хоста.gethostname()— получение имени хоста локальной машины.checkdnsrr()— проверка наличия DNS-записей указанного типа для хоста.ip2long()— преобразование IPv4-адреса в его целочисленное представление.
Заключение
Функция gethostbyaddr() выполняет обратный DNS-поиск, превращая IP-адрес в имя хоста. Ключевая особенность — её поведение при возврате значения: при ненайденном имени хоста она возвращает исходный IP, а false — только при некорректных входных данных, поэтому проверяйте результат внимательно. Используйте её вместе с gethostbyname(), когда требуется прямо-подтверждённый обратный DNS, и никогда не доверяйте непроверенному обратному поиску в вопросах безопасности.