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

Функция getmxrr для получения MX-записей: примеры применения
Раздел: Сетевые функции
getmxrr(string $hostname, array &$hosts, array &$weights = null): bool

Основные сведения о функции getmxrr

Функция getmxrr в PHP предназначена для получения MX-записей (Mail Exchange) указанного доменного имени. MX-записи определяют серверы, ответственные за прием электронной почты для домена. Функция используется для проверки конфигурации почтового сервера, валидации email-адресов и диагностики проблем с доставкой почты.

Аргументы функции
  • hostname (string): Доменное имя, для которого запрашиваются MX-записи. Например, "example.com".
  • hosts (array): Переменная, передаваемая по ссылке. В нее будут записаны найденные MX-хости (массив строк).
  • weights (array): Переменная, передаваемая по ссылке. Если указана, будет заполнена значениями приоритета (веса) для соответствующих MX-записей из массива hosts.

Функция возвращает true, если MX-записи найдены, и false в противном случае.

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

Базовый вызов с получением списка серверов
<?php
$domain = 'gmail.com';
if (getmxrr($domain, $mxhosts)) {
    echo "MX-записи для $domain:" . PHP_EOL;
    print_r($mxhosts);
} else {
    echo "MX-записи для $domain не найдены." . PHP_EOL;
}
?>
MX-записи для gmail.com:
Array
(
    [0] => alt4.gmail-smtp-in.l.google.com
    [1] => alt1.gmail-smtp-in.l.google.com
    [2] => alt2.gmail-smtp-in.l.google.com
    [3] => alt3.gmail-smtp-in.l.google.com
    [4] => gmail-smtp-in.l.google.com
)
Использование с приоритетами (weights)
<?php
$domain = 'yahoo.com';
if (getmxrr($domain, $mxhosts, $weights)) {
    echo "MX-записи с приоритетами для $domain:" . PHP_EOL;
    for ($i = 0; $i < count($mxhosts); $i++) {
        echo "Приоритет: {$weights[$i]}, Хост: {$mxhosts[$i]}" . PHP_EOL;
    }
}
?>
MX-записи с приоритетами для yahoo.com:
Приоритет: 1, Хост: mta7.am0.yahoodns.net
Приоритет: 1, Хост: mta6.am0.yahoodns.net
Приоритет: 1, Хост: mta5.am0.yahoodns.net

Похожие функции в PHP

  • dns_get_record($hostname, DNS_MX): Более универсальная функция для получения различных типов DNS-записей. Возвращает подробный ассоциативный массив с данными, включая приоритет, целевой хост и TTL. Предпочтительнее, когда нужна дополнительная информация или запрос других типов записей (A, TXT, NS).
  • checkdnsrr($hostname, 'MX'): Проверяет наличие записей определенного типа (по умолчанию MX). Возвращает только true/false, не предоставляя самих значений. Используется для быстрой проверки существования записи.

Типичные ошибки и проблемы

Отсутствие расширения

Функция требует наличия модуля PHP, работающего с DNS (обычно это модуль "sockets" или возможность системных вызовов). На некоторых хостах она может быть отключена.

<?php
if (!function_exists('getmxrr')) {
    die('Функция getmxrr не доступна в этой конфигурации PHP.');
}
?>
Некорректное доменное имя
<?php
// При несуществующем домене функция вернет false
$result = getmxrr('nonexistent-domain-xyz987.test', $hosts);
var_dump($result); // bool(false)
?>
Использование переменных без инициализации
<?php
// Ошибки не будет, но код становится менее понятным
$mx = [];
getmxrr('example.com', $mx); // Лучше явно инициализировать $mx как массив
?>

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

В PHP 8.0 поведение функции getmxrr было изменено в отношении обработки ошибок. Ранее при сбое разрешения имени (например, временный сбой DNS) функция могла молча вернуть false. Теперь в таких случаях генерируется предупреждение (E_WARNING). Это делает отладку более явной.

<?php
// В PHP 8 при проблемах с сетью или DNS может появиться warning.
// Рекомендуется использовать @ для подавления или обрабатывать ошибки иначе.
if (@getmxrr('example.com', $mxhosts)) {
    // ...
}
?>

Расширенные примеры применения

Валидация email с проверкой домена
Пример php
<?php
function isEmailDomainValid($email) {
    $parts = explode('@', $email);
    if (count($parts) !== 2) return false;
    $domain = trim($parts[1]);
    // Сначала проверяем существование A или AAAA записи как fallback
    if (checkdnsrr($domain, 'A') || checkdnsrr($domain, 'AAAA')) {
        return true;
    }
    // Затем проверяем MX-записи
    return getmxrr($domain, $mxhosts);
}
$emails = ['user@gmail.com', 'test@invalid-fake-domain-123.xyz'];
foreach ($emails as $email) {
    $valid = isEmailDomainValid($email) ? 'Да' : 'Нет';
    echo "$email - валидный домен: $valid" . PHP_EOL;
}
?>
user@gmail.com - валидный домен: Да
test@invalid-fake-domain-123.xyz - валидный домен: Нет
Сортировка MX-записей по приоритету
Пример php
<?php
function getSortedMxRecords($domain) {
    $mxHosts = [];
    $mxWeights = [];
    if (!getmxrr($domain, $mxHosts, $mxWeights)) {
        return null;
    }
    // Объединяем и сортируем по приоритету (чем меньше вес, тем выше приоритет)
    $combined = [];
    foreach ($mxHosts as $index => $host) {
        $combined[] = ['host' => $host, 'weight' => $mxWeights[$index]];
    }
    usort($combined, function($a, $b) {
        return $a['weight'] <=> $b['weight'];
    });
    return $combined;
}
$sortedMx = getSortedMxRecords('microsoft.com');
if ($sortedMx) {
    foreach ($sortedMx as $record) {
        echo "Хост: {$record['host']}, Приоритет: {$record['weight']}" . PHP_EOL;
    }
}
?>
Пакетная проверка нескольких доменов
Пример php
<?php
$domainsToCheck = ['github.com', 'stackoverflow.com', 'fake.test.loc'];
$results = [];
foreach ($domainsToCheck as $domain) {
    $hasMx = getmxrr($domain, $hosts);
    $results[$domain] = [
        'has_mx' => $hasMx,
        'hosts' => $hasMx ? $hosts : []
    ];
}
print_r($results);
?>
Array
(
    [github.com] => Array
        (
            [has_mx] => 1
            [hosts] => Array
                (
                    [0] => alt2.aspmx.l.google.com
                    [1] => aspmx.l.google.com
                    [2] => alt3.aspmx.l.google.com
                    [3] => alt1.aspmx.l.google.com
                    [4] => alt4.aspmx.l.google.com
                )
        )
    [stackoverflow.com] => Array
        (
            [has_mx] => 1
            [hosts] => Array
                (
                    [0] => aspmx.l.google.com
                    [1] => alt1.aspmx.l.google.com
                    [2] => alt2.aspmx.l.google.com
                )
        )
    [fake.test.loc] => Array
        (
            [has_mx] =>
            [hosts] => Array
                ( )
        )
)

Аналоги в других языках программирования

Getmxrr в Python

import dns.resolver
try:
    answers = dns.resolver.resolve('example.com', 'MX')
    for rdata in answers:
        print(f'Приоритет: {rdata.preference}, Хост: {rdata.exchange}')
except Exception as e:
    print(f'Ошибка: {e}')
JavaScript (Node.js с модулем dns)
const dns = require('dns').promises;
async function getMx(domain) {
    try {
        const records = await dns.resolveMx(domain);
        console.log(records); // массив объектов {priority, exchange}
    } catch (err) {
        console.log('Записи не найдены или ошибка:', err.code);
    }
}
getMx('example.com');

Getmxrr в MySQL

Прямого аналога для запроса MX-записей не существует. Обычно подобная проверка выносится на уровень приложения.

PHP getmxrr function comments

En
Getmxrr Get MX records corresponding to a given Internet host name