PHP

【PHP】NULLや空文字をチェックする時の注意点(isset、empty、is_null)

PHPをやっていると、必ずNULLや空文字のチェックで躓くので(少なくとも自分は、、、)、何度も同じ過ちを繰り返さないようにメモしておきます。

 

この記事の内容

  • イコール2つ(==)でNULLチェックや空文字チェックがうまくいかないのはなぜ?
  • 「==」は比較対象の型チェックを行わない
  • 「===」は比較対象の型チェックを行う
  • 「==」は値の比較をする前に、型をそろえる処理が事前に走る
    • 数値文字は数値に変換
  • PHPでは nullもfalseも空文字も0も値としては同じ(型は違う)!!

経緯

以前PHPでプログラムを書いている時にハマったこと。

例えば、変数$varに「0」が入ってくる場合、NULLチェックと空文字チェックをしたのですが、予期せぬ判定がされました。

 $var = 0;
  if($var == '')   { 内部処理が実行されてしまう } // ケース1
  if($var == NULL) { 内部処理が実行されてしまう } // ケース2
  if(empty($var))  { 内部処理が実行されてしまう } // ケース3

自分としては$varの中身が「0」だから空欄でもNULLでもない認識で、もちろんif文の中には入らないと思っていました。しかしケース1~3では内部処理が実行されてしまいます。

他にもいろいろ試してみた結果、逆に以下のようなケースではif文は内部処理されない!?

 $var = 0;
  if($var === '')   { 内部処理が実行されない } // ケース4
  if($var === NULL) { 内部処理が実行されない } // ケース5
  if(is_null($var)) { 内部処理が実行されない } // ケース6

なんでぇ?

解説

NULLもFALSEも空文字も0も、値は同じ

まずケース1ケース2について解説します。

自分が根本的に勘違いしていたのが、PHPでは NULLもFALSEも空文字も0もすべて同じ値として認識して扱うということです(^^;。

そのためif(0 == NULL)も、if(0 == '')も、if(false == null)も全部判定結果はTRUEとなり、1と2のケースでは内部処理されてしまいます。

 

次にケース3です。

empty関数は、変数が空であるかどうかを検査する関数です。

ここで言う空とは、単に空文字のことではなく以下のものを指すそうです。

空とは

  • "" (空文字列)
  • 0 (整数 の 0)
  • 0.0 (浮動小数点数の 0)
  • "0" (文字列 の 0)
  • NULL
  • FALSE
  • array() (空の配列)

よって、empty関数では$varが仮に0だろうと空文字だろうNULLだろうと、同じものとして判別してしまいます。

 

値比較(==)と型比較(===)

では、なぜケース4~6は0やNULLを区別することができたのでしょうか。

それはif文の条件の「==」と「===」との違いが重要なポイントとなります。

「==」は比較される両者の値が同じどうかのみチェックするのに対し、「===」では両者の値の比較に加えて、同じ型かどうかも比較します。

つまり、PHPでは0も空文字もNULLも同じ値として扱われますが、0はint型、FALSEはboolean型、nullはNULL型とそれぞれデータ型異がなるため、「==」で比較しても同じ値として判別され区別できないのに対し、「===」は区別することができたのです。

※因みに、is_null()は比較対象がNULLかどうかをチェックする関数で、$var===NULLと同じ結果を返します。

説明が分かりずらい可能性も加味して、早見表を作ってみました!

if($var) isset empty is_null
$var=1 TRUE TRUE FALSE FALSE
$var=""; FALSE TRUE TRUE FALSE
$var="0"; FALSE TRUE TRUE FALSE
$var=0; FALSE TRUE TRUE FALSE
$var=NULL; FALSE FALSE TRUE TRUE
$var (初期化なし) FALSE FALSE TRUE TRUE
$var=array() FALSE TRUE TRUE FALSE
$var=array(1) TRUE TRUE FALSE FALSE

下記のサイトを参考にさせて頂きました。

参考:
PHPでnullとfalseと空文字と0は同じ?
PHP: empty - Manual
比較演算子

-PHP