Hi internals,
I would like to gather feedback before drafting an RFC for a small addition
to PHP's DNS functions:
dns_check_mx(string $hostname): bool
The function would check whether a hostname has at least one non-null MX
record.
Today, checkdnsrr($domain, "MX") correctly returns true for a domain
publishing a Null MX record:
example.com. IN MX 0 .
This is correct, since an MX record exists. However, RFC 7505 (
https://www.rfc-editor.org/rfc/rfc7505.html) defines this as an explicit
signal that the domain does not accept email.
I am not proposing any change to checkdnsrr(). It should remain a low-level
DNS record existence check.
Proposed behavior:
- false when there are no MX records;
- false when all MX records are Null MX records;
- true when at least one MX record has an exchange target other than ".".
This would not validate email deliverability or perform SMTP-level checks.
It would only provide a DNS-level distinction between "has an MX record"
and "has a non-null MX record".
If there is interest in this direction, I am willing to work on the RFC and
implementation.
I would appreciate feedback on the scope, naming, and edge cases before
preparing an RFC.
Regards,
Samuel Fontebasso
Am 13.05.2026 um 03:47 schrieb Samuel Fontebasso samuel.txd@gmail.com:
I would like to gather feedback before drafting an RFC for a small addition to PHP's DNS functions:
dns_check_mx(string $hostname): boolThe function would check whether a hostname has at least one non-null MX record.
Proposed behavior:
- false when there are no MX records;
- false when all MX records are Null MX records;
- true when at least one MX record has an exchange target other than ".".
Am I correct that this would be equivalent to the following (example.com http://example.com/ return empty string "" for MX, not a dot ".")?
array_any(
dns_get_record($hostname, DNS_MX),
fn($r) => $r["target"]
)
I'm torn between providing in-core helper functions for common problems (and getmxrr/dns_get_mx is indeed misleading/annoying with its bool return value) but on the other hand I'm not sure checking for an MX is something usually done by the general developer. This sounds more like part of a library/framework as there are further complications when trying to determine about the ability to send email to an address.
Because of this I'd probably not add another helper function and try to handle it on the documentation level instead.
Regards,
- Chris
On Wed, 13 May 2026 09:50:00 +0000, Christian Schneider
cschneid@cschneid.com wrote:
Am I correct that this would be equivalent to the following (example.com <
http://example.com/> return empty string "" for MX, not a dot ".")?
array_any(
dns_get_record($hostname, DNS_MX),
fn($r) => $r["target"]
)
Hi Chris,
Yes, mostly. The raw PHP value for Null MX may be an empty string, as
you noted, but I would still normalize the target so the check is based
on the DNS-level meaning rather than the exact value returned by
dns_get_record():
array_any(
dns_get_record($hostname, DNS_MX),
fn($r) => rtrim($r["target"] ?? "", ".") !== ""
)
I agree this can be done in userland. My point is more about API
semantics: PHP already has DNS-level boolean functions, and RFC 7505
makes "has an MX record" and "has a non-null MX record" two different
DNS-level statements.
I also agree this should not become email deliverability validation. It
should stay strictly limited to MX records.
I am trying to understand whether this DNS-level distinction is worth
exposing explicitly in the existing DNS API.
Regards,
Samuel
Proposed behavior:
- false when there are no MX records;
- false when all MX records are Null MX records;
- true when at least one MX record has an exchange target other than ".".
This would not validate email deliverability or perform SMTP-level checks.
It would only provide a DNS-level distinction between "has an MX record"
and "has a non-null MX record”.
I’d say this isn’t that useful because the absence of an MX record does not mean that a domain cannot receive email.
While the RFC7505 “null MX” approach is not handled explicitly in PHP functions, the fallback of using the A record as an MX still applies, as per
https://datatracker.ietf.org/doc/html/rfc974 and https://www.rfc-editor.org/rfc/rfc5321#section-5.1
So of those three proposed behaviours, only one is actually useful.
Marcus