re: PHPでメールアドレスかどうか調べる方法
はてブでotsuneさんやkazuhookuさんがPHPクオリティについて勘違いしていたので、一言申し上げたところ、参考にされた方がいたようで、もうちょっと補足します。
いくつか実装での「正しいメールアドレス」を調べてみました。
phpspot
function is_mail($text) {
if (preg_match('/^[a-zA-Z0-9_\.\-]+?@[A-Za-z0-9_\.\-]+$/',$text)) {
return TRUE;
} else {
return FALSE;
}
}
PEAR::Mail_RFC822
function isValidInetAddress($data, $strict = false)
{
$regex = $strict ? '/^([.0-9a-z_+-]+)@(([0-9a-z-]+¥.)+[0-9a-z]{2,})$/i' : '/^([*+!.&#$|¥'¥¥%¥/0-9a-z^_`{}=?‾:-]+)@(([0-9a-z-]+¥.)+[0-9a-z]{2,})$/i';
if (preg_match($regex, trim($data), $matches)) {
return array($matches[1], $matches[2]);
} else {
return false;
}
}
CakePHP
define('VALID_EMAIL', '/¥¥A(?:^([a-z0-9][a-z0-9_¥¥-¥¥.¥¥+]*)@([a-z0-9][a-z0-9¥¥.¥¥-]{0,63}¥¥.(com|org|net|biz|info|name|net|pro|aero|coop|museum|[a-z]{2,4}))$)¥¥z/i');
Ethna
function checkMailAddress($mailaddress)
{
if (preg_match('/^([a-z0-9_]|\-|\.|\+)+@(([a-z0-9_]|\-)+\.)+[a-z]{2,6}$/i',
$mailaddress)) {
return true;
}
return false;
symfony
public function execute(&$value, &$error)
{
$strict = $this->getParameterHolder()->get('strict');
if ($strict == true)
{
$re = '/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i';
}
else
{
/* Cal Henderson: http://iamcal.com/publish/articles/php/parsing_email/pdf/
* The long regular expression below is made by the following code
* fragment:
*
* $qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]';
* $dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]';
* $atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c'
* . '\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+';
* $quoted_pair = '\\x5c\\x00-\\x7f';
* $domain_literal = "\\x5b($dtext|$quoted_pair)*\\x5d";
* $quoted_string = "\\x22($qtext|$quoted_pair)*\\x22";
* $domain_ref = $atom;
* $sub_domain = "($domain_ref|$domain_literal)";
* $word = "($atom|$quoted_string)";
* $domain = "$sub_domain(\\x2e$sub_domain)*";
* $local_part = "$word(\\x2e$word)*";
* $addr_spec = "$local_part\\x40$domain";
*/
$re = '/^([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-'
.'\\x5d\\x7f-\\xff]+|\\x22([^\\x0d\\x22\\x5c\\x80-\\xff]|\\x5c\\x00-'
.'\\x7f)*\\x22)(\\x2e([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-'
.'\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x22([^\\x0d\\x22\\x5c\\x80'
.'-\\xff]|\\x5c\\x00-\\x7f)*\\x22))*\\x40([^\\x00-\\x20\\x22\\x28\\x29'
.'\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x5b([^'
.'\\x0d\\x5b-\\x5d\\x80-\\xff]|\\x5c\\x00-\\x7f)*\\x5d)(\\x2e([^\\x00-'
.'\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-'
.'\\xff]+|\\x5b([^\\x0d\\x5b-\\x5d\\x80-\\xff]|\\x5c\\x00-\\x7f)*'
.'\\x5d))*$/'
;
}
if (!preg_match($re, $value))
{
$error = $this->getParameterHolder()->get('email_error');
return false;
}
$checkDomain = $this->getParameterHolder()->get('check_domain');
if ($checkDomain && function_exists('checkdnsrr'))
{
$tokens = explode('@', $value);
if (!checkdnsrr($tokens[1], 'MX') && !checkdnsrr($tokens[1], 'A'))
{
$error = $this->getParameterHolder()->get('email_error');
return false;
}
}
return true;
}
結論。DNS引いてドメインの有効性チェックまでやるsymfonyはヤリ過ぎ。EthnaかPEAR、symfonyのstrictでないものが現実的な線かと思います。
- Posted on 2007/06/01
- パーマリンク
- コメント (3)
- トラックバック (3)
コメント (3)
友人のソフトバンク携帯メールアドレスは
?hogehoge@
みたいに、?で始まるのだが、弾かれる可能性がある。
そもそも?ではじまるのっていいの?って意見もあるからむずかしい。
Posted by ? | 2007/06/02 13:10
それよりシニア向けサイト作ってみろよ
メールアドレス入れられませんって問い合わせ来たら
東京都~~の住所入れようとしてた。
メアドなんて正しくても、送れるか見れるかなんて確証はないからなんでもいいんだよ 正常なものが拒否されるのは痛いが
Posted by 1232 | 2007/10/19 02:39
>>1232
それでも、メールアドレスのチェックは必要です。
登録は出来るようにしたとしても、その明らかに間違ったメールアドレスにメールを送ろうとするのは間違ったやり方でしょう。
メール送信の前にメールアドレスのチェックは必要だと思います。
そういう意味では、symfonyのやり方がやりすぎというのも一概には言えません。
何のためにメールアドレスをチェックするのかという視点が抜けています。
それに、1232さんの例ではむしろ、問い合わせが来たのは幸運だったのではありませんか?
もしそのまま登録されていたら、その人に連絡する術がないのではないですか?
Posted by よう | 2007/10/22 10:36