W3docs

Función PHP dns_get_record(): Todo lo que necesitas saber

Como desarrollador PHP, puede que necesites obtener distintos tipos de registros DNS para un dominio. La función dns_get_record() de PHP es ideal para ello.

Cuando tu código necesita buscar el servidor de correo de un dominio, verificar que un nombre de host se resuelve o leer los registros SPF/TXT detrás de una comprobación de entregabilidad de email, necesitas acceso al Sistema de Nombres de Dominio (DNS). La función integrada dns_get_record() de PHP realiza esa consulta a nivel de protocolo y te devuelve los registros como un array de PHP — sin necesidad de ejecutar dig externamente.

Este capítulo cubre la firma de la función, los tipos de registros que puede obtener, la forma exacta del array que devuelve, cómo leer las secciones autoritativa y adicional de una respuesta DNS, y los errores comunes que suelen confundir a los desarrolladores (especialmente la diferencia entre DNS_ANY y la combinación de constantes específicas).

Aviso de deprecación. dns_get_record() fue declarada obsoleta en PHP 8.3 y está previsto que se elimine en una versión posterior. Para código nuevo, es preferible usar la extensión getdns, una biblioteca de resolución de terceros (como react/dns), o los helpers más limitados checkdnsrr() y gethostbyname() cuando solo necesitas una respuesta de sí/no o un único registro A. Los conceptos que se describen a continuación siguen siendo válidos para esas alternativas.

Qué hace dns_get_record()

dns_get_record() consulta el DNS para un nombre de dominio y devuelve los registros de recursos coincidentes como un array de arrays asociativos. Tú eliges qué tipo de registro obtener (A, MX, TXT, etc.). A diferencia de gethostbyname(), que solo resuelve un nombre de host a una única dirección IPv4, dns_get_record() expone el registro completo — TTL, prioridad, destino y campos específicos del tipo.

Sintaxis

dns_get_record(
    string $hostname,
    int $type = DNS_ANY,
    array &$authoritative_name_servers = null,
    array &$additional_records = null,
    bool $raw = false
): array|false
ParámetroDescripción
$hostnameEl nombre de dominio a consultar, p. ej. "php.net".
$typeUna constante DNS_* que selecciona el tipo de registro. Opcional; por defecto es DNS_ANY. Puedes combinar constantes con OR — `DNS_A
&$authoritative_name_serversSe rellena por referencia con los registros del servidor de nombres autoritativo (NS) devueltos en la sección de autoridad de la respuesta.
&$additional_recordsSe rellena por referencia con los registros adicionales (glue) que devuelve el servidor.
$rawCuando es true, consulta únicamente el $type exacto y devuelve los registros en formato crudo. Por defecto es false.

Devuelve un array de registros, o false en caso de fallo (por ejemplo, cuando el nombre de host no existe o el resolvedor no está disponible).

Una consulta básica

Cada registro devuelto es un array asociativo. Todos los registros contienen las claves host, class, type y ttl; las claves restantes dependen del tipo de registro.

<?php

$records = dns_get_record("php.net", DNS_A);

print_r($records);

Un resultado típico tiene este aspecto (la IP y el TTL variarán):

Array
(
    [0] => Array
        (
            [host] => php.net
            [class] => IN
            [ttl] => 3600
            [type] => A
            [ip] => 185.85.0.29
        )
)

Como el resultado es un array simple, puedes iterarlo con foreach y leer los campos de cada registro directamente:

<?php

foreach (dns_get_record("php.net", DNS_A) as $record) {
    echo $record['host'] . " -> " . $record['ip'] . "\n";
}

Tipos de registros comunes

Pasa una de estas constantes DNS_* como argumento $type. Las claves específicas del tipo que puedes esperar se muestran junto a cada una.

ConstanteRegistroClaves específicas del tipo
DNS_ADirección IPv4ip
DNS_AAAADirección IPv6ipv6
DNS_MXIntercambiador de correopri, target
DNS_NSServidor de nombres autoritativotarget
DNS_CNAMENombre canónico (alias)target
DNS_TXTRegistro de texto (SPF, verificación)txt, entries
DNS_SOAInicio de autoridadmname, rname, serial, …
DNS_ANYCualquier tipo que devuelva el resolvedorvaría

Para obtener varios tipos a la vez, combina las constantes con el operador OR a nivel de bits (|):

<?php

// A + MX records in a single call
$records = dns_get_record("php.net", DNS_A | DNS_MX);

foreach ($records as $record) {
    echo $record['type'] . "\n";
}

Error común — DNS_ANY vs combinar constantes. DNS_ANY emite una única consulta ANY, y muchos resolvedores y servidores autoritativos ahora la rechazan o la truncan (RFC 8482). Si quieres registros específicos, combina las constantes precisas con OR (DNS_A | DNS_MX | DNS_TXT) en lugar de depender de DNS_ANY — es más fiable y más eficiente.

Lectura de registros autoritativos y adicionales

El tercer y cuarto parámetro se rellenan por referencia. Exponen las secciones de autoridad y adicionales de la respuesta DNS, lo cual es útil cuando necesitas los servidores de nombres que respondieron o los registros A de adhesión para un destino MX:

<?php

$authns = [];
$addtl  = [];

$records = dns_get_record("php.net", DNS_MX, $authns, $addtl);

echo "MX records: "         . count($records) . "\n";
echo "Authoritative NS: "   . count($authns)  . "\n";
echo "Additional records: " . count($addtl)   . "\n";

Gestión de fallos

dns_get_record() devuelve false cuando la consulta falla. Comprueba siempre este caso antes de iterar; de lo contrario, un foreach sobre false genera una advertencia:

<?php

$records = dns_get_record("definitely-not-a-real-domain.invalid", DNS_A);

if ($records === false || $records === []) {
    echo "No records found.\n";
} else {
    print_r($records);
}

Para una comprobación simple de "¿existe este registro?", checkdnsrr() es más ligero, ya que devuelve un boolean en lugar de construir el array de registros completo.

Ejemplo práctico: validar el MX de un dominio de email

Un uso común en el mundo real es confirmar que una dirección de email pertenece a un dominio que realmente puede recibir correo — útil después de que filter_var() haya validado el formato de la dirección:

<?php

function domainCanReceiveMail(string $email): bool
{
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        return false;
    }

    $domain = substr(strrchr($email, "@"), 1);
    $mx = dns_get_record($domain, DNS_MX);

    return is_array($mx) && count($mx) > 0;
}

var_dump(domainCanReceiveMail("[email protected]")); // bool(true)

La validación de formato y la existencia del MX son condiciones necesarias pero no suficientes — no prueban que el buzón específico exista. Son un primer filtro económico que atrapa errores tipográficos y dominios desechables antes de intentar enviar el mensaje.

Conclusión

dns_get_record() ofrece a PHP acceso directo y estructurado a los datos DNS: elige un tipo de registro con una constante DNS_*, itera el array devuelto y lee los campos específicos del tipo. Prefiere combinar constantes precisas con OR en lugar de usar DNS_ANY, comprueba siempre la posibilidad de un retorno false, y recurre a checkdnsrr() o gethostbyname() cuando necesitas una respuesta más concreta. Como la función está en proceso de eliminación de PHP, aísla las consultas DNS detrás de un pequeño helper para que puedas sustituirla por la extensión getdns o una biblioteca de resolución más adelante sin modificar el resto de tu código.

Práctica

Práctica
¿Cuál es el propósito de la función dns_get_record() en PHP?
¿Cuál es el propósito de la función dns_get_record() en PHP?
Was this page helpful?