Функция PHP getmxrr(): всё, что нужно знать
Как PHP-разработчику вам может понадобиться получить MX-записи для домена. Узнайте, как работает устаревшая функция getmxrr() и чем её заменить.
Как PHP-разработчику, вам может понадобиться получить записи почтового обмена (MX) для заданного доменного имени. В таких сценариях исторически использовалась функция getmxrr(). Важно: функция getmxrr() была объявлена устаревшей в PHP 8.2 и удалена в PHP 8.4. Для современных PHP-приложений вместо неё следует использовать dns_get_record(). В этой статье описывается устаревшая функция для поддержки старых кодовых баз.
Что такое функция getmxrr()?
Функция getmxrr() выполняет DNS-запрос для указанного доменного имени и возвращает array всех связанных MX-записей. Для её работы необходимо, чтобы в вашем PHP-окружении было включено расширение dns. Функция возвращает true в случае успеха и false в случае неудачи.
Как использовать функцию getmxrr()
Использование функции getmxrr() довольно простое. Вот синтаксис функции:
Синтаксис PHP функции getmxrr()
getmxrr($hostname, &$mxhosts, &$weight);Функция принимает три параметра:
$hostname: доменное имя, для которого нужно получить MX-записи.$mxhosts: ссылка на array, в котором будут храниться MX-хосты для доменного имени. (Примечание: в PHP 5.3+ символ&требуется только в сигнатуре функции, но не при её вызове.)$weight: ссылка на array, в котором будут храниться весовые приоритеты MX-хостов.
Вот пример использования функции getmxrr() для получения MX-записей доменного имени:
Как использовать функцию getmxrr()?
В этом примере мы получаем MX-записи для доменного имени «example.com». Функция выполняет DNS-запрос и заполняет массивы $mxhosts и $weight. Затем мы перебираем элементы массивов и выводим MX-хосты и их веса. Если поиск завершается неудачей, блок else корректно обрабатывает ошибку.
Понимание весов MX (приоритетов)
Каждая MX-запись имеет вес (также называемый приоритетом или предпочтением). Когда почтовый сервер доставляет письмо, он в первую очередь пробует хост с наименьшим весом; хосты с более высоким весом выступают в роли запасных. Таким образом, запись с весом 10 предпочтительнее записи с весом 20.
Функция getmxrr() не сортирует результаты — записи возвращаются в том порядке, в котором их возвращает DNS-резолвер. Если нужно получить их в порядке доставки, отсортируйте по весу самостоятельно. Поскольку $mxhosts и $weight — параллельные массивы (индекс 0 одного соответствует индексу 0 другого), чистый способ сохранить их согласованность при сортировке — сначала объединить их:
<?php
$hostname = "example.com";
$mxhosts = [];
$weight = [];
if (getmxrr($hostname, $mxhosts, $weight)) {
// Pair each host with its weight, then sort by weight ascending.
$records = array_map(fn($host, $w) => ['host' => $host, 'weight' => $w], $mxhosts, $weight);
usort($records, fn($a, $b) => $a['weight'] <=> $b['weight']);
foreach ($records as $record) {
echo "Priority {$record['weight']}: {$record['host']}\n";
}
} else {
echo "No MX record found for $hostname";
}Теперь цикл выводит наиболее предпочтительный почтовый сервер первым.
Возвращаемое значение и распространённые подводные камни
- Тип возвращаемого значения — boolean.
getmxrr()возвращаетtrue, если найдена хотя бы одна MX-запись, иfalseв противном случае. Фактические данные записываются в массивы$mxhostsи$weight, передаваемые по ссылке, — а не возвращаются. - Отсутствие MX-записей не означает отсутствие домена. Домен может резолвиться (иметь запись
A), но не иметь MX-записей — в этом случаеgetmxrr()вернётfalse. Согласно стандарту SMTP, почта всё равно может быть доставлена наA-запись хоста в качестве запасного варианта, однакоgetmxrr()об этом не сообщит. - Завершающие точки. Возвращаемые имена хостов могут содержать завершающую точку (например,
mail.example.com.). Удаляйте её при сравнении строк:rtrim($host, '.'). - Требуется расширение
dns. В большинстве сборок оно компилируется по умолчанию, однако в минимальных или защищённых средах оно может быть отключено.
Современная замена: dns_get_record()
Поскольку функция getmxrr() удалена в PHP 8.4, в новом коде следует использовать dns_get_record() с флагом DNS_MX. Она возвращает единый, более богатый array вместо двух параллельных:
<?php
$hostname = "example.com";
$records = dns_get_record($hostname, DNS_MX);
if ($records) {
// Sort by the 'pri' (priority/weight) field, lowest first.
usort($records, fn($a, $b) => $a['pri'] <=> $b['pri']);
foreach ($records as $record) {
echo "Priority {$record['pri']}: {$record['target']}\n";
}
} else {
echo "No MX record found for $hostname";
}Каждый элемент здесь является ассоциативным array с ключами host, type, pri и target, поэтому вам не нужно синхронно управлять двумя массивами. Это рекомендуемый подход для любого PHP 8.x проекта.
Связанные функции
dns_get_record()— современный, полностью поддерживаемый способ чтения любого типа DNS-записей, включая MX.dns_get_mx()— процедурный псевдонимgetmxrr(); то же поведение, то же устаревание.checkdnsrr()— проверка наличия DNS-записей заданного типа для хоста.gethostbyname()— преобразование имени хоста в его IPv4-записьA.
Заключение
Функция getmxrr() — это устаревший инструмент для получения MX-записей в старых версиях PHP. Понимая её синтаксис и поведение, вы можете поддерживать совместимость с устаревшими кодовыми базами. Для новых проектов мы рекомендуем использовать dns_get_record() с флагом типа DNS_MX. Надеемся, что эта статья была полезной для работы с историческими DNS-функциями PHP.