質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.10%

真偽値の確認について

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 800

score 136

以下のコードは拝見させて頂いておりました、Qiitaの記事にて記載されておりましたコードになります。

$email = (string)filter_input(INPUT_POST, 'email');

/* 2. 値の形式に関するバリデーション */
if (false !== filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo "正しいEメールアドレスです: $email\n";
} else {
    echo "Eメールアドレスの形式が不正です: $email\n";
}


上記コードのif (false !== filter_var($email, FILTER_VALIDATE_EMAIL)) {こちらの部分をif ( filter_var($email, FILTER_VALIDATE_EMAIL)) {こちらに置き換えても挙動は同じでしょうか?
以下のコードで値を入力し試してみた限りでは、同じように思えましたが、確証がなかった為、質問させて貰いました。

<?php
$email = (string)filter_input(INPUT_POST, 'email');

/* 2. 値の形式に関するバリデーション */
if (false !== filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo "正しいEメールアドレスです: $email\n";
} else {
    echo "Eメールアドレスの形式が不正です: $email\n";
}

?>

<form  method="post">
    <input type="text" name="email">
    <input type="submit" value="送信">
</form>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+4

今回のケースに限って言えば、FILTER_VALIDATE_EMAILでfilter_var()した戻り値が
0やnullや空配列になることはないので書き換えは可能ですが
falseでないということは厳密に比較することでバグを減らす効果が期待できます。
「!==false」の癖をつけておいた方が今後のためなります

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/07/04 14:46

    ご回答ありがとうございます。
    falseでない場合を明確に判定したい場合は、「!==false」こちらの書き方は有用という訳ですね。

    キャンセル

  • 2019/07/04 16:33

    すみません。
    ご回答頂きました中で一点お聞きしたい部分があるのですが、FILTER_VALIDATE_EMAILでfilter_var()した戻り値が0やnullや空配列になることはない、というのは、「$email = (string)filter_input(INPUT_POST, 'email');」こちらでstringへのキャストを行っているからでしょうか?

    キャンセル

checkベストアンサー

+2

たとえば、

filter_var("abcd0!!!", FILTER_SANITIZE_NUMBER_INT)

の値は、数字以外が除去され、"0" が残ります。

したがって、それをifで評価するとfalseになってしまいます。

<?php
if (filter_var("abcd0!!!", FILTER_SANITIZE_NUMBER_INT)) {
    echo "TRUE";
} else {
    echo "FALSE";
}
if (false !== filter_var("abcd0!!!", FILTER_SANITIZE_NUMBER_INT)) {
    echo "TRUE";
} else {
    echo "FALSE";
}

上記のようなコードを書くと、結果が違ってくるので、falseと比較するものだと思っておいたほうが安全です。

検証フィルタ の場合は確かに挙動に違いはないといえそうですが、filter_varを使うときはfalseと比較する、と考えておいたほうが安全かなと考えます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/07/04 15:38

    「真理値としてみると地雷を踏む」例として有名なものには、strposもあります。「先頭で見つかった場合」は(int)0、「見つからなかった場合」はfalseを返しますので、多くの場合にこの峻別が必須となります。

    (preg_matchの「エラーが発生した場合」って、正規表現自体がおかしい場合以外はどういう状況なんだろうか…)

    キャンセル

  • 2019/07/04 15:42

    ただの例です。
    filter_vars を説明するためにあえて注意しなくてはいけない点として記載しています。検証フィルタについては後半で説明していますし、質問者の方も納得しているのでまあ良いのかなとは思っています。

    キャンセル

  • 2019/07/04 15:53

    例として適切ではないと指摘しています。

    また、検証フィルタの記述に関しても間違いがあります。
    FILTER_VALIDATE_BOOLEAN
    FILTER_VALIDATE_REGEXP
    に関して確認/修正されると良いです。

    キャンセル

+1

PHPマニュアルを確認しますと

filter_var()
返り値 ¶
フィルタリングされたデータ、あるいは処理に失敗した場合に FALSE を返します。

ですが、おおよそ同じ挙動になるものと思います。
ただ、「失敗した場合にFALSEを返す」というのが仕様的に明示されているため(成功した場合は正しいメールアドレス)、
「それ以外である」という表現をするため筆者はあえてfalse !== 
確実に返ってくる内容をもとに判断させているものと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/07/04 15:00

    なるほど...
    FALSEでないということを明確に判定したい場合は、「false !== 」こちらの書き方は有用ですね。

    キャンセル

  • 2019/07/04 15:06

    はい。そこは他のフィルタリングもあわせてPHPマニュアルの仕様を確認してみると良いです。

    キャンセル

+1

本件の本質は、php の型変換です。
if(f(x)) と if(f(x)!==false) は等価ではありません。

PHP 型の比較表ページにある「PHP 関数による $x の比較」表の右列「boolean : if($x)」を見るとかなり多くの型が、false へ変換されることがわかると思います。

ただ、すでに別の回答にあるように、今回のケースでは検証対象が「email アドレス」で「FILTER_VALIDATE_EMAIL」を使用しているので、事実上問題は発生しないです。

余談
php の型変換は、非常にやっかいです。型変換への理解がよほどのものでなければ比較には型変換を伴わない「厳密な比較」を使用することをオススメします。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.10%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る