Gethostbynamel: примеры (PHP)

Получение списка IP-адресов по имени хоста с помощью gethostbynamel
Раздел: Сетевые функции
gethostbynamel(string $hostname): array|false
Описание функции gethostbynamel

Функция gethostbynamel() в PHP возвращает массив IPv4-адресов, соответствующих указанному имени хоста (доменному имени). Эта функция используется для разрешения имен хостов в IP-адреса, когда возможно наличие нескольких записей A в DNS.

Когда используется

Функция применяется в случаях, когда необходимо получить все IPv4-адреса, связанные с доменным именем. Это бывает полезно для балансировки нагрузки, создания зеркал, проверки доступности хоста через разные IP или при работе с сервисами, у которых несколько точек входа.

Аргументы функции

Функция принимает один обязательный параметр:

  • hostname (string) – имя хоста (домен), которое требуется разрешить в IP-адреса.

Возвращаемое значение: массив IPv4-адресов в виде строк в случае успеха. Если имя хоста не может быть разрешено, функция возвращает false.

Примеры использования gethostbynamel
Базовое использование

Получение всех IP-адресов для домена google.com.

<?php
$hostname = "google.com";
$addresses = gethostbynamel($hostname);

if ($addresses !== false) {
    print_r($addresses);
} else {
    echo "Не удалось разрешить $hostname";
}
?>
Array
(
    [0] => 142.250.185.206
    [1] => 142.250.185.238
    // ... другие IP-адреса
)
Обработка неудачного разрешения

Попытка разрешить несуществующее доменное имя.

<?php
$hostname = "non-existent-example-domain-12345.com";
$result = gethostbynamel($hostname);

var_dump($result);
?>
bool(false)
Похожие функции в PHP

Возвращает первый (основной) IPv4-адрес для указанного имени хоста. Используется, когда нужен только один адрес, а не все.

$ip = gethostbyname('example.com'); // Возвращает строку с IP
dns_get_record()

Возвращает различные DNS-записи, включая A, AAAA, MX, TXT и другие. Функция предоставляет больше информации и поддерживает IPv6. Предпочтительнее, когда требуется гибкость и получение разных типов записей.

$dns = dns_get_record('php.net', DNS_A); // Возвращает массив записей A
checkdnsrr()

Проверяет существование DNS-записей определенного типа для заданного хоста. Полезна для быстрой проверки, существует ли запись.

if (checkdnsrr('example.com', 'A')) {
    echo 'Запись A существует';
}
Типичные ошибки
Отсутствие проверки на false

Использование результата функции как массива без проверки может привести к ошибке.

<?php
$ips = gethostbynamel('invalid-host-xyz');
// Ошибка, если $ips === false
foreach ($ips as $ip) {
    echo $ip;
}
?>
Warning: Invalid argument supplied for foreach()
Ожидание IPv6-адресов

Функция gethostbynamel() возвращает только IPv4-адреса. Для получения IPv6 нужно использовать dns_get_record() с типом DNS_AAAA.

$ipv6 = dns_get_record('example.com', DNS_AAAA);
Блокирующий вызов

Функция выполняется синхронно и может блокировать выполнение скрипта при проблемах с сетью или DNS. В высоконагруженных приложениях это может стать проблемой.

Изменения в последних версиях PHP

Функция gethostbynamel() осталась практически неизменной на протяжении многих версий PHP, включая PHP 8. Основные изменения связаны с общей обработкой ошибок и типами возвращаемых значений, которые стали более строгими.

В PHP 8.0 и выше, в связи с ужесточением типизации, важно проверять возвращаемое значение, так как false возвращается именно в случае ошибки.

Расширенные примеры
Проверка доступности хоста по разным IP

Попытка соединения с хостом через один из его IP-адресов.

Пример php
<?php
function check_host_availability($hostname, $port = 80, $timeout = 2) {
    $ips = gethostbynamel($hostname);
    if ($ips === false) return false;

    foreach ($ips as $ip) {
        $socket = @fsockopen($ip, $port, $errno, $errstr, $timeout);
        if ($socket) {
            fclose($socket);
            return $ip; // Возвращаем первый работающий IP
        }
    }
    return false;
}

$available_ip = check_host_availability('php.net');
echo $available_ip ? "Доступен через IP: $available_ip" : "Не доступен";
?>
Доступен через IP: 144.76.78.159
Сравнение списков IP для разных поддоменов

Определение, используют ли разные поддомены одни и те же IP-адреса.

Пример php
<?php
$subdomains = ['www.php.net', 'docs.php.net', 'news.php.net'];
$ip_lists = [];

foreach ($subdomains as $sub) {
    $ips = gethostbynamel($sub);
    if ($ips) $ip_lists[$sub] = $ips;
}

// Сравнение массивов IP
$common_ips = call_user_func_array('array_intersect', $ip_lists);
print_r($common_ips);
?>
Array
(
    [0] => 144.76.78.159
)
Генерация списка всех уникальных IP для набора доменов
Пример php
<?php
$domains = ['google.com', 'github.com', 'stackoverflow.com'];
$all_ips = [];

foreach ($domains as $domain) {
    $ips = gethostbynamel($domain);
    if ($ips) $all_ips = array_merge($all_ips, $ips);
}

$unique_ips = array_unique($all_ips);
print_r($unique_ips);
?>
Array
(
    [0] => 142.250.185.206
    [1] => 142.250.185.238
    [2] => 140.82.121.3
    [3] => 151.101.65.69
    [4] => 151.101.193.69
)
Аналоги функции в других языках

Gethostbynamel в Python

Используется функция socket.gethostbyname_ex(), возвращающая кортеж с именем хоста, списком псевдонимов и списком IP-адресов.

import socket
try:
    hostname, aliaslist, ipaddrlist = socket.gethostbyname_ex('google.com')
    print('IP-адреса:', ipaddrlist)
except socket.gaierror:
    print('Ошибка разрешения имени')
IP-адреса: ['142.250.185.206', '142.250.185.238']
JavaScript (Node.js)

В Node.js для разрешения имен используется модуль dns с асинхронными методами, например, dns.resolve4().

const dns = require('dns');
dns.resolve4('google.com', (err, addresses) => {
    if (err) throw err;
    console.log('IP-адреса:', addresses);
});
IP-адреса: [ '142.250.185.206', '142.250.185.238' ]

Gethostbynamel в MySQL

В MySQL косвенно можно использовать встроенную функцию SUBSTRING_INDEX() для извлечения IP из строк, но прямого аналога для DNS-запросов нет.

PHP gethostbynamel function comments

En
Gethostbynamel Get a list of IPv4 addresses corresponding to a given Internet host name