58

我发现一些网站声称可以验证电子邮件地址是否有效。是否可以仅使用 PHP 检查电子邮件地址是否有效?

<?php
    if($_POST['email'] != ''){
        // The email to validate
        $email = $_POST['email'];

        // An optional sender
        function domain_exists($email, $record = 'MX'){
            list($user, $domain) = explode('@', $email);
            return checkdnsrr($domain, $record);
        }
        if(domain_exists($email)) {
            echo('This MX records exists; I will accept this email as valid.');
        }
        else {
            echo('No MX record exists;  Invalid email.');
        }
    }
?>
<form method="POST">
    <input type="text" name="email">
    <input type="submit" value="submit">
</form>

这就是我现在所拥有的。它检查域是否存在但无法检查用户的电子邮件是否存在于该域中。是否可以使用 PHP 做到这一点?

4

3 回答 3

49

您应该检查 SMTP。

这意味着您必须连接到该电子邮件的 SMTP 服务器。

连接到 SMTP 服务器后,您应该发送以下命令:

HELO somehostname.com
MAIL FROM: <no-reply@gmail.com>
RCPT TO: <emailtovalidate@domain.com>

如果您收到“<emailtovalidate@domain.com> 中继访问被拒绝”,则表示此电子邮件无效。

有一个简单的 PHP 类。你可以使用它:

http://www.phpclasses.org/package/6650-PHP-Check-if-an-e-mail-is-valid-using-SMTP.html

于 2013-10-09T05:00:24.007 回答
43

如果仅使用一种 PHP 方法,您无法验证(以足够的准确性依赖)电子邮件是否确实存在。您可以向该帐户发送电子邮件,但仅此一项也无法验证该帐户是否存在(见下文)。您至少可以验证它的格式至少类似于

if(filter_var($email, FILTER_VALIDATE_EMAIL)) {
    //Email is valid
}

如果需要,您可以添加另一个检查。解析域,然后运行​​checkdnsrr

if(checkdnsrr($domain)) {
     // Domain at least has an MX record, necessary to receive email
}

许多人到了这一点,仍然不相信那里没有一些隐藏的方法。如果您有义务并决心验证电子邮件,请参考以下注意事项:

  1. 垃圾邮件发送者也知道“连接技巧”(您开始发送电子邮件并依靠服务器在该点反弹)。其他答案之一链接到该库,该库有此警告

    一些邮件服务器会静默拒绝测试邮件,以防止垃圾邮件发送者检查其用户的电子邮件并过滤有效电子邮件,因此此功能可能不适用于所有邮件服务器。

    换句话说,如果存在无效地址,您可能不会收到无效地址响应。事实上,几乎所有的邮件服务器都带有一个选项来接受所有传入的邮件(这里是如何使用 Postfix 来做的)。链接到验证库的答案忽略了提及该警告。

  2. 垃圾邮件黑名单。他们按 IP 地址列入黑名单,如果您的服务器不断地进行验证连接,您就有可能在 Spamhaus 或其他阻止列表中清盘。如果您被列入黑名单,验证电子邮件地址对您有什么好处?

  3. 如果验证电子邮件地址真的那么重要,那么公认的方法是强制用户回复电子邮件。向他们发送一封完整的电子邮件,其中包含他们必须单击以进行验证的链接。这不是垃圾邮件,您可以保证任何回复都有一个有效的地址。

于 2013-10-09T03:07:48.677 回答
4

我整个早上都在寻找同样的答案,并且几乎发现不可能验证您需要检查的每个电子邮件地址是否在您需要验证的时候确实存在。因此,作为一种解决方法,我创建了一个简单的PHP脚本来验证电子邮件地址的格式是否正确,并且它还验证使用的域名是否正确。

GitHub这里https://github.com/DukeOfMarshall/PHP---JSON-Email-Verification/tree/master

<?php

# What to do if the class is being called directly and not being included in a script     via PHP
# This allows the class/script to be called via other methods like JavaScript

if(basename(__FILE__) == basename($_SERVER["SCRIPT_FILENAME"])){
$return_array = array();

if($_GET['address_to_verify'] == '' || !isset($_GET['address_to_verify'])){
    $return_array['error']              = 1;
    $return_array['message']            = 'No email address was submitted for verification';
    $return_array['domain_verified']    = 0;
    $return_array['format_verified']    = 0;
}else{
    $verify = new EmailVerify();

    if($verify->verify_formatting($_GET['address_to_verify'])){
        $return_array['format_verified']    = 1;

        if($verify->verify_domain($_GET['address_to_verify'])){
            $return_array['error']              = 0;
            $return_array['domain_verified']    = 1;
            $return_array['message']            = 'Formatting and domain have been verified';
        }else{
            $return_array['error']              = 1;
            $return_array['domain_verified']    = 0;
            $return_array['message']            = 'Formatting was verified, but verification of the domain has failed';
        }
    }else{
        $return_array['error']              = 1;
        $return_array['domain_verified']    = 0;
        $return_array['format_verified']    = 0;
        $return_array['message']            = 'Email was not formatted correctly';
    }
}

echo json_encode($return_array);

exit();
}

class EmailVerify {
public function __construct(){

}

public function verify_domain($address_to_verify){
    // an optional sender  
    $record = 'MX';
    list($user, $domain) = explode('@', $address_to_verify);
    return checkdnsrr($domain, $record);
}

public function verify_formatting($address_to_verify){
    if(strstr($address_to_verify, "@") == FALSE){
        return false;
    }else{
        list($user, $domain) = explode('@', $address_to_verify);

        if(strstr($domain, '.') == FALSE){
            return false;
        }else{
            return true;
        }
    }
    }
}
?>
于 2014-03-05T16:36:26.830 回答