PHPではempty()で判定をしてはいけない

Laravel
目次

キッカケ

PHPで空配列かどうかの判定をする際、empty()は避けるべきというツイートが流れてきました。

「emptyは禁止」

ぎゅう

あ、empty()使ってました

ぎゅう

でもなぜダメなんだろう?
具体的に学習してみようか

ちょうどempty()で判定をした処理を実装していたので、なぜemptyがダメなのか学習することにしました。

empty()の特性を知る

emptyの判定を下記の表いまとめてみました。

if($var)issetemptyis_null
$var=1truetruefalsefalse
$var=””;falsetruetruefalse
$var=”0″;falsetruetruefalse
$var=0;falsetruetruefalse
$var=NULL;falsefalsetruetrue
$varfalsefalsetruetrue
$var=array()falsetruetruefalse
$var=array(1)truetruefalsefalse

表で分かる通り、empty()はtrueに返すケースが多すぎます。

つまり、意図しない動作が発生する可能性が高いです。

例えば、empty()で判定をして[]が存在する想定だったが、実際にはNULLや未定義の変数かもしれません。

そうなると、配列でしか使用できない関数や処理でエラーになる可能性があります。

型定義をすれば、多少回避は可能?

今回empty()は配列でないケースでもtrue判定をすることがわかりました。

とはいえ、内容的にはempty()でtrueにしてもよさそうな気もします。

そこで、じゃあシンプルにどうすれば回避できるのだろうか?と考えていきましょう。

まず、引数の型でarrayを指定すれば、判定を限定できるはずです。

    /**
     * 添付ファイルを作成
     * 
     * @param array $files
     * @return bool
     */
    public function createFiles(array $files): bool
    {   
        if(!empty($files)) {
            return $this->documentRepository->insert(
                $files
            );
        }

        return false;
    }

サクッと例を書いてみました。

    public function createFiles(array $files): bool

引数の型にarrayを指定している場合は、empty()も空配列の判定に限定できます。

if($var)issetemptyis_null
$var=array()falsetruetruefalse
$var=array(1)truetruefalsefalse

しかしながら、仕様変更などでarrayではなく他のクラスを型指定するかもしれません。

そういった変更を考慮すると、この方法では保証しきれないとわかります。

empty()の代替え案

どうやってemptyの代替え案を考えるために、改めて表を確認しましょう

if($var)issetemptyis_null
$var=1truetruefalsefalse
$var=””;falsetruetruefalse
$var=”0″;falsetruetruefalse
$var=0;falsetruetruefalse
$var=NULL;falsefalsetruetrue
$varfalsefalsetruetrue
$var=array()falsetruetruefalse
$var=array(1)truetruefalsefalse

表のメソッドの条件を整理すると、 if($var)での判定を利用するしかないとわかります。

  • issetは配列全般をtrueに判定してしまう。
  • is_nullは配列全般をfalseに判定してしまう。

if(!$var)を使用した判定の場合、is_array()を組み合わせて判定させます。

if (is_array($var) && !$var)

ちょっとわかりづらいですよね。

そこでもっとシンプルに判定をします。

if ($var === [])

そもそもempty()の判定なので、$var === []でシンプルに空配列の判定できます。

これを理解すると、empty()は使わなくてよいと結論に達します。

まとめ

empty()の判定はtrueが多く、意図しない処理をする可能性がある。

基本的に$var === []で判定を完結できるので、こちらを利用しましょう。

ぎゅう
WEBエンジニア
渋谷でWEBエンジニアとして働く。
LaravelとVue.jsをよく取り扱い、誰でも仕様が伝わるコードを書くことを得意とする。
先輩だろうがプルリクにコメントをして、リファクタしまくる仕様伝わるコード書くマン
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次
閉じる