如何通过编程查询邮件服务器的连接及配置信息?
Great question—let’s break this down step by step, since I’ve tackled nearly identical challenges when building email automation tools for user-submitted addresses.
1. Public Databases/Methods to Query Mail Server Info
You don’t always need a paid database—DNS records are the primary free, reliable source for this data. That said, there are also free REST APIs that wrap DNS lookups (and add extra context) if you don’t want to handle DNS directly in PHP.
PHP Implementation (Direct DNS Lookup)
PHP has built-in functions to fetch MX, SRV, and other DNS records—this is the most lightweight, cost-free approach. MX records tell you the mail exchange servers for a domain, while SRV records explicitly define service endpoints (like IMAP/SMTP with ports and security protocols).
REST Service Options
Several free-tier HTTP REST services let you pass an email domain and get structured server info. Most offer free quotas (e.g., 100-1000 queries/day) that work for small-scale apps. These services return JSON responses with MX, SRV, port, and protocol details without requiring external dependencies.
2. Identifying Server Types (POP3/IMAP/SMTP), Ports, & Security Protocols
The most accurate way is to check SRV records, which are designed to map service types to specific servers and ports. If SRV records don’t exist, fall back to testing standard ports with connection checks.
Step 1: Use SRV Records (PHP Example)
SRV records follow this format: _service._protocol.domain.com. Here’s how to fetch them in PHP:
function fetchEmailServiceRecords($domain) { $results = []; // Get MX records (required for basic mail routing) if (getmxrr($domain, $mxHosts, $mxWeights)) { $results['mx_servers'] = array_combine($mxHosts, $mxWeights); } // Fetch SMTP-related SRV records (TLS/SSL) $smtpTLS = dns_get_record("_submission._tcp.$domain", DNS_SRV); if (!empty($smtpTLS)) $results['smtp_tls'] = $smtpTLS; // Port 587 typically $smtpSSL = dns_get_record("_smtps._tcp.$domain", DNS_SRV); if (!empty($smtpSSL)) $results['smtp_ssl'] = $smtpSSL; // Port 465 typically // Fetch IMAP-related SRV records $imap = dns_get_record("_imap._tcp.$domain", DNS_SRV); if (!empty($imap)) $results['imap'] = $imap; // Port 143 $imapSSL = dns_get_record("_imaps._tcp.$domain", DNS_SRV); if (!empty($imapSSL)) $results['imap_ssl'] = $imapSSL; // Port 993 // Fetch POP3-related SRV records $pop3 = dns_get_record("_pop3._tcp.$domain", DNS_SRV); if (!empty($pop3)) $results['pop3'] = $pop3; // Port 110 $pop3SSL = dns_get_record("_pop3s._tcp.$domain", DNS_SRV); if (!empty($pop3SSL)) $results['pop3_ssl'] = $pop3SSL; // Port 995 return $results; } // Usage: Extract domain from email and fetch records $email = "hello.world@example.com"; $domain = substr(strrchr($email, "@"), 1); $serverData = fetchEmailServiceRecords($domain); print_r($serverData);
Step 2: Fallback to Port Testing (If No SRV Records)
If SRV records are missing, test standard ports to confirm connectivity and protocol support. Here’s a PHP snippet to test SMTP TLS:
function testSmtpTLS($host, $port = 587) { $socket = @fsockopen("tls://$host", $port, $errno, $errstr, 10); if (!$socket) return false; // Validate server response $response = fgets($socket, 1024); if (strpos($response, "220") === false) { fclose($socket); return false; } // Send EHLO to confirm TLS support fwrite($socket, "EHLO yourdomain.com\r\n"); $response = fgets($socket, 1024); fclose($socket); return strpos($response, "250") !== false; } // Test example.com's SMTP TLS $isValid = testSmtpTLS("smtp.example.com");
3. Checking if Mail Server Domain Differs From Email Suffix
This is common with virtual hosts (e.g., user@mycustomdomain.com uses smtp.hostingprovider.com as its MX server). To check this:
- Extract the domain from the email.
- Fetch its MX records.
- Compare each MX server’s domain to the email’s suffix.
Here’s a PHP function to do this:
function isMailServerExternal($email) { $emailDomain = rtrim(substr(strrchr($email, "@"), 1), "."); if (!getmxrr($emailDomain, $mxHosts)) return false; foreach ($mxHosts as $mxHost) { $mxDomain = rtrim($mxHost, "."); // Check if MX host is not a subdomain or match of the email domain if (strpos($mxDomain, $emailDomain) === false) { return true; } } return false; } // Example: Check if virtual host is used $email = "user@mycustomdomain.com"; $isExternal = isMailServerExternal($email); echo $isExternal ? "Mail server is external (virtual host)" : "Mail server matches email domain";
4. Free vs. Paid Options
- Free: Direct DNS lookups via PHP are 100% free and sufficient for most use cases. Free REST APIs also work for small traffic volumes (check their free tiers).
- Paid: Only necessary if you need high query volumes, global DNS coverage, additional data (like server reputation), or managed APIs with uptime guarantees. Most paid services offer pay-as-you-go plans starting at a few dollars per month.
内容的提问来源于stack exchange,提问作者Michael Sohnen

