4

如何在 PHP 中检查重复的电子邮件地址,同时考虑到 Gmail 的自动标记器和标点符号?

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

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

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

4

7 回答 7

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];
于 2009-10-19T00:14:24.687 回答
2

在比较之前将地址剥离为基本形式。制作一个normalise()将剥离标签的功能,然后删除所有点。然后您可以通过以下方式比较地址:

normalise(address1) == normalise(address2)

如果您必须经常这样做,请将地址也保存为规范化形式,这样您就不必经常将它们转换回来。

于 2009-10-19T00:04:52.133 回答
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;
    }
}
于 2017-03-11T14:12:01.747 回答
1

也许这会更好地命名为“如何在 PHP 中规范化 gmail 地址,考虑 (user.name+label@gmail.com)”

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

我有自己的域 example.com,并且任何发往该域中任何地址的电子邮件都会进入我的单个邮箱。现在,您是否要检查以将我的 example.com 上的任何内容标准化为您端的单个地址?

通过官方电子邮件地址格式,您尝试匹配的那些地址是不同的。

于 2009-10-19T00:49:51.543 回答
1

电子邮件地址解析非常非常难以正确执行,不会破坏事物和烦人的用户..

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

如果您确定需要这样做,请先阅读rfc0822,然后修改此电子邮件地址解析正则表达式以提取电子邮件的所有部分,然后将它们重新组合,不包括标签..

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

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

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

于 2009-10-19T00:51:29.450 回答
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 地址中包含多个“点”符号的电子邮件被视为无效。在某些情况下,这不是合乎逻辑的解决方案,但这对我有用。

于 2011-07-19T08:29:00.737 回答
-1
function normalize($input) {
     $input = str_replace('.', '', $input);
     $pattern = '/\+(\w+)@/';
     return preg_replace($pattern, '@', $input);
}
于 2009-10-19T00:26:43.073 回答