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

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

ただいまの
回答率

88.06%

PHPでif (isset($hoge) && !empty($hoge)) しないといけないパターンとは?

解決済

回答 5

投稿

  • 評価
  • クリップ 1
  • VIEW 7,462

score 149

よくPHPの値存在チェックで

if (isset($hoge['page']) && !empty($hoge['page'])) {
    ....
}

みたいな空チェックを見る気がしますが、いつも
if (!empty($hoge['page']) {
    ...
}
みたいに!empty()判定だけでいいのではと思ってしまいます。

!empty()単一だとどういうパターンで危険なのでしょうか。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 5

checkベストアンサー

+4

まとめると・・・恐らく下記のどちらかではないかと思います

  • empty が notice を発生させないことを知らない人が誤って冗長に記述した
  • もとは isset や empty の中に式が書かれていたが改修によってただの連想配列に置き換えられた

後者はちょっと考えにくいと思うので、前者の可能性が高いと思います。

また、

よくPHPの値存在チェックで ~~~ みたいな空チェックを見る気がします

とありますが、わたし自身はあまり見たことないです。
empty だけで十分ではないでしょうか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/07/08 14:07

    なるほど、やはりあまり意味はなかったのですね。ご回答ありがとうございました!

    キャンセル

+3

「変数が存在しなくても警告は発生しません。 つまり、empty() は本質的に !isset($var) || $var == false と同じことを簡潔に記述しているだけです。」
引用:http://php.net/manual/ja/function.empty.php

別に「!empty()」このコードでも問題無いと思います。
ただ、PHP5.5以前では式に対応していなかったので未だにちょっとemptyは嫌厭してしまいます。

「!」だけですと「ん?」となってしまう人もいると思いますので個人的に書くとしたら

if ( empty($hoge['page']) === FALSE )
{

}
みたいに書きます。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/07/08 00:04

    自分の環境(PHP5.4.42とPHP5.3.2)ではNULLが返ってくるのみでNoticeが出ないのですが、Noticeが出るのはどの様な環境なのでしょうか…?

    キャンセル

  • 2015/07/08 09:03 編集

    Noticeが出ます。
    出ないとしたらerror_reportingやdisplay_errorsの設定を見直しましょう。

    キャンセル

  • 2015/07/08 10:01 編集

    まず、質問者の方を差し置いたコメントをしてしまった事をお詫び申し上げます。

    nanndemoiikaraさん、回答して下さりありがとうございました。

    キャンセル

+1

$_POST、$_REQUEST 等のパラメータチェックの際に役立ちます。

例えばチェックボックスは、PHPで受け取れるようにするには、ご存知かとは存じますが以下のように項目名に"[]"を付ける必要があります。

<input type="checkbox" name="para[]" value="パラメータA">
<input type="checkbox" name="para[]" value="パラメータB">
<input type="checkbox" name="para[]" value="パラメータC">

このパラメータをPHP 側で受け取るには、以下のように記載します。

//チェックボックスのパラメータを取得する
$chkbox_para = $_REQUEST["para"];

// 使用例
echo $chkbox_para[0];
echo $chkbox_para[1];
しかし、ここで問題なのがチェックボックスを全部選択せずに送信すると、$_REQUEST["para"]自体がフォームから送信されないため、

$chkbox_para = $_REQUEST["para"];
foreach($chkbox_para as $key => $value)
{
    echo $value;
}
というような処理をすると、実行エラーとなります。
これを回避するには、

if (isset($_REQUEST["para"] == true)
{
    $chkbox_para = $_REQUEST["para"];
    foreach($chkbox_para as $key => $value)
    {
        echo $value;
    }
}
と記述します。

また他の例としては、以下のようなデータベースの内容を確認の際にも重宝します。

■table1
key・・・主キー
name・・・名前
flg・・・識別フラグ (default null / 1 or 2 or 3)
select文で
select name from table1;
と記述し、flgを読まなくても良い出力パターンの時に、以下のような記述に役立ちます。

// データを読む
$read_buff = db_read_sample();

//flg あり、なし共通出力

while(データの読める間)
{
    $name = $read_buff["name"];
    $out_flg = null;

    if (isset($read_buff["flg"]) == true)
    {
        switch($read_buff["flg"])
        {
        case 1 :
            $out_flg = "条件Aを選択";
            break;           

        case 2 :
            $out_flg = "条件Bを選択";
            break;           

        case 3 :
            $out_flg = "条件Cを選択";
            break;           

        default :
            $out_flg = "条件が選択されていません";
    break;
    }

    //結果を出力
    if ($out_flg != null)
    {
        echo "名前:${name}  条件: ${out_flg}";
    }
    else
    {
        echo "名前:${name}";
    }
}

このように、
①パラメータ自体が存在していなければ何もしない
②パラメータがNULLならばエラー処理をする

を区別するような場合に重宝します。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/07/08 10:02

    KenjiObata様の主張には全て同意致します。
    ただ
    if (isset($hoge['page']) && !empty($hoge['page']))

    if (!empty($hoge['page'])
    この様に書いてはダメなの?

    という質問に対してのissetの説明の回答は適切ではないのでは?
    と思ってしまいます。

    キャンセル

  • 2015/07/08 11:34

    回答ありがとうございます。
    主旨がずれているようでしたらご容赦ください。

    ご質問内容が、

    !empty()判定だけでよいのではないか?
    isset()は不要でないのか?

    という意味にとらえてしまったため、isset()の必要例を記載しておりました。
    大変失礼いたしました。

    キャンセル

0

値が何かによると思いますが、より厳密にチェックするためだと思います。
例えば次のコードを実行すると異なる結果が出る事が分かります。
$value = "";

var_dump( isset( $value ), !empty( $value ) );
PHPマニュアルにある型の比較表を見ると理解しやすいのではないでしょうか。

追記
この回答は正しくありません。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/07/07 22:03

    質問に記載の内容なら、比較すべきは

    <?php
    $value = "";
    var_dump(
    isset($value) && !empty($value),
    !empty($value)
    );

    ではないでしょうか?

    キャンセル

  • 2015/07/07 22:28

    確かにその通りですね。
    また、私の回答だと連想配列ではないので、その点でも正確な回答ではありませんでした。
    コメントを頂いたことで私の理解も進みそうです。
    ありがとうございます。

    キャンセル

0

if (!empty($hoge['page']) {
    ...
}

単一のパターンの場合、その連想配列名が存在しない時にNoticeが表示されたと思います。
それを回避すべく、連想配列の中に対象データの存在確認が必要になります。
エラーレベル等で、Noticeを表示しないような制御を行っている場合など特に気にする問題ではありませんが、厳密にエラーチェックを行おうとするのであれば、

if (isset($hoge['page']) && !empty($hoge['page'])) {
    ....
}

の方が良いかと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/07/07 22:57 編集

    > 単一のパターンの場合、その連想配列名が存在しない時にNoticeが表示されたと思います。
    Notice発生しませんよ

    > エラーレベル等で、Noticeを表示しないような制御を行っている場合など特に気にする問題ではありませんが、厳密にエラーチェックを行おうとするのであれば、
    emptyはerror_reportingでE_ALLを指定してもNoticeは発生しませんよ。

    http://php.net/manual/ja/function.empty.php

    キャンセル

  • 2015/07/07 23:18

    PHP5.4以降の環境では発生しないみたいですね。

    私の場合、PHP4系統からシステムの開発を行っているので、上記の記述の用に対応する癖がついていたためつい・・・。

    運用するサーバの環境依存で、記述内容が変わると思います。
    PHPのバージョンが必ずしも最新とも限りませんので、おまじない的に覚えておくと良いかもですね。

    キャンセル

  • 2015/07/07 23:56

    > PHP5.4以降の環境では発生しないみたいですね。

    少なくとも PHP 4.3.0 の時点で発生しないようです。
    http://3v4l.org/moQpk

    キャンセル

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

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

関連した質問

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