CakePHP で docomo と au の RFC 非準拠メールアドレスを例外的に許可する email バリデーション

CakePHP の組み込みバリデーションルール email
メールアドレスの書式をチェックしてくれて便利なんだけど
特に携帯のキャリアメールに関して困ることがある。

かつて docomo と au で
RFC 違反というか非準拠のアドレスが登録可能だった。
具体的に言うと .(ドット)が連続するものと
@ の直前に . があるもの。

今はもうこれらは登録できないはずだけど
以前に作られたアドレスはまだ生きていて
実際に使っている人もたくさんいる。

使われてはいるけれども
メールアドレスの仕様には沿っていないので
これを入力すると email のバリデーションで弾かれてしまいますね。

yabmin に登録しようとした人からも
「なんかアドレス入れたらおこられるんですけど」
という声がたまに寄せられるので
これらを例外的に許可するバリデーションルールを作りました。

CakePHP 1.2 と 1.3 と、たぶん 2.0 で動くはず。
(一部修正しました。文末に追記あり。 @tbsmcd ご指摘感謝!)

//For PHP 5.3.x or later
public function emailExtended($data, $deep = false) {
    $pattern = '/.+@(docomo.ne.jp|ezweb.ne.jp)$/i';
    $check = preg_replace_callback($pattern, function($matches) {
        $patterns = array('/\.{2,}/', '/\.@/');
        $replacements = array('.', '@');
        return preg_replace($patterns, $replacements, $matches[0]);
    }, array_shift($data));
    return Validation::email($check, $deep);
}

上記は PHP 5.3 から組み込まれた無名関数を使っているので
5.2 までだったらこんな感じですか。

//For PHP 5.2.x or earlier
public function emailExtended($data, $deep = false) {
    $pattern = '/.+@(docomo.ne.jp|ezweb.ne.jp)$/i';
    $check = preg_replace_callback($pattern, create_function('$matches', '
        $patterns = array("/\.{2,}/", "/\.@/");
        $replacements = array(".", "@");
        return preg_replace($patterns, $replacements, $matches[0]);
    '), array_shift($data));
    return Validation::email($check, $deep);
}

これを AppModel か、またはメールアドレスを扱うモデルに書いておいて
バリデーションルールを指定するときはこんな感じで。

public $validate = array(
    'email' => array(
        'rule' => array('emailExtended'),
        'message' => 'メールアドレスがほげほげです。',
    ),
);

頻繁に使いそうならもうプラグインにしてしまってもいいですね。

これ日本で携帯向けのウェブサービスを作るときはよく出くわす問題なので
似たようなのやもっと素晴らしいのを誰かが作ってるかもしれませんけど、
そんなことは知らん。

追記

当初、正規表現の部分を

$pattern = '/[email protected](docomo.ne.jp|ezweb.ne.jp)$/i';

としてたんだけど、これ間違いですね。

機関区 : CakePHP docomo/ezweb の email バリデーションについて

ここにある正規表現だと、実際に存在する docomo, ezweb 以外のドメインも受け入れてしまうので(docomo-ne.jp とか)

修正しました。

$pattern = '/[email protected](docomo|ezweb)\.ne\.jp$/i';

ご指摘ありがとうございました!

  • このエントリーをはてなブックマークに追加