考虑使用Gmail(user.name+label@gmail.com),如何在PHP中检查重复的电子邮件地址

时间:2009-10-18 23:56:39

标签: php gmail duplicates detection email-validation

如何检查PHP中的重复电子邮件地址,是否有可能使用Gmail的自动贴标机和标点符号?

例如,我希望将这些地址检测为重复项:

         username@gmail.com
        user.name@gmail.com
   username+label@gmail.com
  user.name+label@gmail.com

尽管丹尼尔·A·怀特声称:在Gmail中,“@”(和标签)之前随机位置的点可以随意放置。 user.name@gmail.com和username@gmail.com实际上是同一个用户。

7 个答案:

答案 0 :(得分:6)

$email_parts    = explode('@', $email);

// check if there is a "+" and return the string before
$before_plus    = strstr($email_parts[0], '+', TRUE);
$before_at      = $before_plus ? $before_plus : $email_parts[0];

// remove "."
$before_at      = str_replace('.', '', $before_at);

$email_clean    = $before_at.'@'.$email_parts[1];

答案 1 :(得分:2)

在比较之前将地址删除到基本表单。创建一个将剥离标签的函数normalise(),然后删除所有点。然后您可以通过以下方式比较地址:

normalise(address1) == normalise(address2)

如果您经常这样做,请将地址保存为标准化格式,这样您就不必经常转换它们。

答案 2 :(得分:2)

这个答案是@ powtac答案的改进。我需要这个功能来使用gmail打败来自同一个人的多个注册。

if ( ! function_exists('normalize_email'))
{
    /**
     * to normalize emails to a base format, especially for gmail
     * @param $email
     * @return string
     */
    function normalize_email($email) {
        // ensure email is lowercase because of pending in_array check, and more...
        $email = strtolower($email);
        $parts    = explode('@', $email);

        // normalize gmail addresses
        if (in_array($parts[1], ['gmail.com', 'googlemail.com'])) {
            // check if there is a "+" and return the string before then remove "."
            $before_plus    = strstr($parts[0], '+', TRUE);
            $before_at      = str_replace('.', '', $before_plus ? $before_plus : $parts[0]);

            // ensure only @gmail.com addresses are used
            $email    = $before_at.'@gmail.com';
        }

        return $email;
    }
}

答案 3 :(得分:1)

考虑到(user.name+label@gmail.com)

,或许这会更好地标题为“如何在PHP中规范化gmail地址”

您有两种技术解决方案。我会走另一条路,问你为什么要这样做。对我来说感觉不对。您是否试图阻止某人使用不同的电子邮件地址在您的网站上多次注册?这只会阻止这种情况的特殊情况。

我有自己的域名example.com,任何发往该域名地址的电子邮件都会转到我的单个邮箱。您现在是否想要检查以将我的example.com上的任何内容规范化为您的一个地址?

通过official e-mail address format,您尝试匹配的地址不同。

答案 4 :(得分:1)

电子邮件地址解析确实非常难以正确执行,不会破坏用户和讨厌的用户..

首先,我会质疑你是否真的需要这样做?为什么你有多个电子邮件地址,有不同的子地址?

如果您确定需要这样做,请先阅读rfc0822,然后修改this email address parsing regex以提取电子邮件的所有部分,并重新排除这些部分,不包括标签..

稍微多一点..实际上,电子邮件地址维基百科页面有一部分关于地址格式Sub-addressing的这一部分。

发布的代码powtac看起来应该可以正常工作 - 只要你没有以自动方式使用它来删除帐户或任何东西,它应该没问题。

请注意,“自动贴标机”不是GMail特有的功能,Gmail只是推广它。其他邮件服务器支持此功能,一些使用+作为分隔符,另一些使用-。如果您要访问GMail地址中的特殊情况空间,请记住同时考虑googlemail.com

答案 5 :(得分:1)

我已经像这样扩展了Zend Validator。

<?php
class My_Validate_EmailAddress extends Zend_Validate_EmailAddress
{
    public function isValid($value)
    {
        $valid = parent::isValid($value);
        if ($valid
                && in_array($this->_hostname, array('gmail.com', 'googlemail.com'))
                && substr_count($this->_localPart, '.') > 1) {
            $this->_error(parent::INVALID_HOSTNAME);
            $valid = false;
        }
        return valid;
    }
}

gmail地址中带有多个“点”符号的电子邮件被视为无效。在某些情况下,这不是合乎逻辑的解决方案,但这对我有用。

答案 6 :(得分:0)

function normalize($input) {
     $input = str_replace('.', '', $input);
     $pattern = '/\+(\w+)@/';
     return preg_replace($pattern, '@', $input);
}