Funzione PHP dns_get_record(): tutto quello che devi sapere
Scopri come usare la funzione PHP dns_get_record() per ottenere vari tipi di record DNS per un nome di dominio.
Quando il tuo codice deve cercare il server di posta per un dominio, verificare che un hostname si risolva o leggere i record SPF/TXT alla base di un controllo di deliverability delle email, hai bisogno di accedere al Domain Name System (DNS). La funzione integrata di PHP dns_get_record() esegue quella ricerca a livello di protocollo e ti restituisce i record come un array PHP — senza dover ricorrere a dig.
Questo capitolo tratta la firma della funzione, i tipi di record che può recuperare, la struttura esatta dell'array che restituisce, come leggere le sezioni autorevole e aggiuntiva di una risposta DNS e le insidie più comuni (in particolare la differenza tra DNS_ANY e la combinazione di costanti specifiche).
Avviso di deprecazione.
dns_get_record()è stata deprecata in PHP 8.3 ed è prevista la sua rimozione in una versione successiva. Per il nuovo codice, preferisci l'estensionegetdns, una libreria resolver di terze parti (comereact/dns) o gli helper più specificicheckdnsrr()egethostbyname()quando hai bisogno solo di una risposta sì/no o di un singolo record A. I concetti descritti di seguito si applicano comunque a queste alternative.
Cosa fa dns_get_record()
dns_get_record() interroga il DNS per un nome di dominio e restituisce i resource record corrispondenti come un array di array associativi. Scegli quale tipo di record recuperare (A, MX, TXT, ecc.). A differenza di gethostbyname(), che risolve un hostname solo in un singolo indirizzo IPv4, dns_get_record() espone il record completo — TTL, priorità, target e campi specifici del tipo.
Sintassi
dns_get_record(
string $hostname,
int $type = DNS_ANY,
array &$authoritative_name_servers = null,
array &$additional_records = null,
bool $raw = false
): array|false| Parametro | Descrizione |
|---|---|
$hostname | Il nome di dominio da cercare, es. "php.net". |
$type | Una costante DNS_* che seleziona il tipo di record. Opzionale; il valore predefinito è DNS_ANY. Puoi unire le costanti con l'operatore OR — `DNS_A |
&$authoritative_name_servers | Riempito per riferimento con i record del nameserver autorevole (NS) restituiti nella sezione authority della risposta. |
&$additional_records | Riempito per riferimento con i record aggiuntivi (glue) restituiti dal server. |
$raw | Quando è true, interroga solo l'esatto $type e restituisce i record in forma grezza. Il valore predefinito è false. |
Restituisce un array di record oppure false in caso di errore (ad esempio quando il hostname non esiste o il resolver non è raggiungibile).
Una ricerca di base
Ogni record restituito è un array associativo. Ogni record contiene le chiavi host, class, type e ttl; le chiavi rimanenti dipendono dal tipo di record.
<?php
$records = dns_get_record("php.net", DNS_A);
print_r($records);Un risultato tipico è simile a questo (l'IP e il TTL varieranno):
Array
(
[0] => Array
(
[host] => php.net
[class] => IN
[ttl] => 3600
[type] => A
[ip] => 185.85.0.29
)
)Poiché il risultato è un semplice array, lo si itera con foreach e si leggono direttamente i campi di ciascun record:
<?php
foreach (dns_get_record("php.net", DNS_A) as $record) {
echo $record['host'] . " -> " . $record['ip'] . "\n";
}Tipi di record comuni
Passa una di queste costanti DNS_* come argomento $type. Le chiavi specifiche del tipo che puoi aspettarti sono elencate accanto a ciascuna.
| Costante | Record | Chiavi specifiche del tipo |
|---|---|---|
DNS_A | Indirizzo IPv4 | ip |
DNS_AAAA | Indirizzo IPv6 | ipv6 |
DNS_MX | Mail exchanger | pri, target |
DNS_NS | Nameserver autorevole | target |
DNS_CNAME | Nome canonico (alias) | target |
DNS_TXT | Record di testo (SPF, verifica) | txt, entries |
DNS_SOA | Start of authority | mname, rname, serial, … |
DNS_ANY | Qualsiasi tipo restituito dal resolver | varia |
Per recuperare più tipi contemporaneamente, combina le costanti con l'operatore OR bit a bit (|):
<?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";
}Attenzione —
DNS_ANYvs combinazione di costanti.DNS_ANYinvia una singola queryANY, e molti resolver e server autorevoli ora la rifiutano o la troncano (RFC 8482). Se vuoi record specifici, unisci le costanti precise con OR (DNS_A | DNS_MX | DNS_TXT) invece di affidarti aDNS_ANY— è più affidabile ed efficiente.
Lettura dei record autorevoli e aggiuntivi
Il terzo e il quarto parametro vengono riempiti per riferimento. Espongono le sezioni authority e additional della risposta DNS, utili quando hai bisogno dei nameserver che hanno risposto o dei record A glue per un target 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";Gestione degli errori
dns_get_record() restituisce false quando la ricerca fallisce. Controlla sempre prima di iterare, altrimenti un foreach su false genera un avviso:
<?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);
}Per un semplice controllo "questo record esiste?", checkdnsrr() è più leggero, poiché restituisce un boolean invece di costruire l'intero array di record.
Esempio pratico: validare l'MX del dominio di un'email
Un caso d'uso comune nel mondo reale è verificare che un indirizzo email appartenga a un dominio che può effettivamente ricevere posta — utile dopo che filter_var() ha validato il formato dell'indirizzo:
<?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 validazione del formato e l'esistenza dell'MX sono necessarie ma non sufficienti — non dimostrano che la casella di posta specifica esista. Sono un filtro preliminare economico che cattura errori di battitura e domini temporanei prima che tu tenti di inviare.
Conclusione
dns_get_record() offre a PHP un accesso diretto e strutturato ai dati DNS: scegli un tipo di record con una costante DNS_*, itera l'array restituito e leggi i campi specifici del tipo. Preferisci combinare costanti precise con OR invece di usare DNS_ANY, controlla sempre il ritorno di false e usa checkdnsrr() o gethostbyname() quando hai bisogno di una risposta più limitata. Poiché la funzione è in via di eliminazione da PHP, isola le ricerche DNS dietro un piccolo helper così potrai sostituire l'estensione getdns o una libreria resolver in seguito senza dover modificare il resto del codice.