PHPでメールアドレスを判定し処理を分岐する方法|filter_varとtrim・存在確認

ユーザー登録などで、入力されたメールアドレスの形式が正しいかを判定する処理は頻出です。PHPでは filter_var() で簡単に判定でき、自前の正規表現より確実です。この記事では基本に加え、前後の空白で弾かれる落とし穴や、ドメインの存在確認、判定結果での分岐処理まで解説します。

この記事の結論:形式判定は filter_var($email, FILTER_VALIDATE_EMAIL)。ただし前後に空白があると弾かれるので、先に trim() します。形式OKでも実在するとは限らないため、必要なら checkdnsrr() でドメインを確認します。
スポンサーリンク

filter_varで形式を判定する

FILTER_VALIDATE_EMAIL を指定すると、メールアドレスとして妥当なら値を、そうでなければ false を返します。自前の正規表現よりRFCに沿った確実な判定ができます。

基本の形式判定
<?php
$email = "example@example.com";

if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo "有効な形式です";
} else {
    echo "無効な形式です";
}

注意:前後の空白があると弾かれる

意外な落とし穴です。FILTER_VALIDATE_EMAIL前後にスペースがあると無効と判定します。フォーム入力ではコピペで空白が混ざりがちなので、先に trim() しましょう。

trimしてから検証
<?php
$input = " example@example.com "; // 前後に空白

var_dump(filter_var($input, FILTER_VALIDATE_EMAIL));       // false(空白で弾かれる)
var_dump(filter_var(trim($input), FILTER_VALIDATE_EMAIL)); // "example@example.com"

判定結果で処理を分岐する

フォーム送信時に、形式チェックしてエラー表示か登録処理に分岐する例です。画面に出すときは htmlspecialchars() でXSS対策をします。

フォームの分岐処理
<?php
$email = trim($_POST["email"] ?? "");

if ($email === "") {
    $error = "メールアドレスを入力してください";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $error = "メールアドレスの形式が正しくありません";
} else {
    // 形式OK → 登録などの処理へ
    // ... 登録処理 ...
    $error = null;
}

if ($error !== null) {
    echo htmlspecialchars($error, ENT_QUOTES, "UTF-8");
}
判定後にページ遷移させたい場合はリダイレクトを行う方法、URLの判定はURLかどうかを判定する方法が同様の考え方で参考になります。

ドメインが実在するか確認する(checkdnsrr)

filter_var()形式しか見ません。「そのアドレスが実際に存在するか」までは分かりません。ドメインがメール受信可能か(MXレコードがあるか)を簡易確認するには checkdnsrr() が使えます。

ドメインのMXレコードを確認
<?php
$email = "user@example.com";

if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $domain = substr(strrchr($email, "@"), 1); // @以降のドメイン
    if (checkdnsrr($domain, "MX")) {
        echo "ドメインはメールを受信できそうです";
    } else {
        echo "ドメインにMXレコードがありません";
    }
}
checkdnsrr() でMXレコードを確認できても、そのアドレス(ユーザー名部分)が実在するとは限りません。本当に有効かを確かめる確実な方法は、確認メールを送ってリンクを踏んでもらうこと(メール認証)です。

よくある質問(FAQ)

Qメールアドレスの判定は正規表現を自作すべきですか?
Aいいえ。filter_var($email, FILTER_VALIDATE_EMAIL) を使うのが確実です。メールアドレスの正しい正規表現は非常に複雑で、自作すると漏れや誤判定が起きやすいためです。
Q正しいはずのアドレスが無効と判定されます。
A前後に空白が入っていないか確認してください。FILTER_VALIDATE_EMAIL は空白付きを無効とするため、trim($email) してから判定します。
Q形式が正しければ実在するメールアドレスですか?
Aいいえ。filter_varは形式しか確認しません。ドメインの受信可否は checkdnsrr($domain, "MX") で簡易確認できますが、アドレスの実在を確かめるには確認メールの送信が確実です。
Q入力が空のときはどう扱いますか?
A空文字は filter_var で無効になりますが、「未入力」と「形式エラー」でメッセージを分けたいなら、先に if ($email === "") で未入力を判定すると親切です。

まとめ

PHPのメールアドレス判定のポイントを整理します。

  • 形式判定は filter_var($email, FILTER_VALIDATE_EMAIL)(正規表現の自作は不要)
  • 前後の空白で弾かれるので、先に trim() する
  • 出力時は htmlspecialchars() でXSS対策
  • ドメインの受信可否は checkdnsrr($domain, "MX")
  • 実在確認は確認メールの送信が確実

関連として、URLかどうかを判定する方法文字列パターンの確認方法リダイレクトを行う方法もあわせて読むと、入力検証と分岐処理に強くなれます。