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óngetdns, una biblioteca de resolución de terceros (comoreact/dns), o los helpers más limitadoscheckdnsrr()ygethostbyname()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ámetro | Descripción |
|---|---|
$hostname | El nombre de dominio a consultar, p. ej. "php.net". |
$type | Una constante DNS_* que selecciona el tipo de registro. Opcional; por defecto es DNS_ANY. Puedes combinar constantes con OR — `DNS_A |
&$authoritative_name_servers | Se rellena por referencia con los registros del servidor de nombres autoritativo (NS) devueltos en la sección de autoridad de la respuesta. |
&$additional_records | Se rellena por referencia con los registros adicionales (glue) que devuelve el servidor. |
$raw | Cuando 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.
| Constante | Registro | Claves específicas del tipo |
|---|---|---|
DNS_A | Dirección IPv4 | ip |
DNS_AAAA | Dirección IPv6 | ipv6 |
DNS_MX | Intercambiador de correo | pri, target |
DNS_NS | Servidor de nombres autoritativo | target |
DNS_CNAME | Nombre canónico (alias) | target |
DNS_TXT | Registro de texto (SPF, verificación) | txt, entries |
DNS_SOA | Inicio de autoridad | mname, rname, serial, … |
DNS_ANY | Cualquier tipo que devuelva el resolvedor | varí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_ANYvs combinar constantes.DNS_ANYemite una única consultaANY, 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 deDNS_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.