ホームページ制作 オフィスオバタ

PHPで「0」と「false」と「null」を区別する

PHPを組んでいると時折「あれ?」となる動きをすることがあります。
よくあるのが、正常なのにfalse判定になるなどです。

原因は値が「0」になっており、それをfalse判断になってしまったためです。
事実、表現が違うだけで中身は同じです。

ここで疑問に思いました。
「0」と「false」は区別をつけることができないものか?

ググって調べて対処することができましたので忘備録として記録いたします。

現象はこのような感じです

今回検証用に用意したものがこちらです。

<?php
$table = array(false, 0, null);

foreach($table AS $value)
{
	if ($value == false)
	{
		echo " false ";
	}
	else if ($value == 0)
	{
		echo " zero ";
	}
	else if ($value == null)
	{
		echo " null ";
	}
}

?>

配列に「false」「0」「null」をセットし、それぞれif文で区別できるかテストしてみました。
その結果がこちらです。

全部 false判定になりました。
どうやら0もnullもfalseとして扱われています。

何とかする方法を調べたら意外と簡単な方法で解決できました。

「0」と「false」が同一判定されると、何かと不具合の原因になります。
識別する方法がないかとググってみたところ、あっさりと解決しました。
それがこちらの方法です。

if文では== で同じかどうか比較します。
このイコール2つ並べるのを3つ(===)にすることで、0とfalseを区別できました。

実際にやってみたものがこちら

<?php
$table = array(false, 0, null);

foreach($table AS $value)
{
	if ($value === false)
	{
		echo " false ";
	}
	else if ($value === 0)
	{
		echo " zero ";
	}
	else if ($value === null)
	{
		echo " null ";
	}
}

?>

「false」と「0」と「null」の識別がちゃんとできました。

ちなみに否定形の判断もできました。

if文では「同じか?」という判断よりも、「異なるか?」という判断のほうが多いです。
例えば「エラーでない場合処理」というようなケースです。

その場合 != という記述をしますが、これだと「false」「0」「null」は同じ扱いになりました。
そこで、!== と記述したところ、「false」「0」「null」が区別できました。

これで肯定判断、否定判断どちらも対応ができます。

なぜ条件式を3文字にすると区別がつくのか?

「false」と「0」と「null」は、== 2文字だと同じ扱いになるのに、=== 3文字だと区別がつきます。
なぜそうなるのか調べてみました。

「false」と「0」と「null」は中身は同じですがデータ型が異なります

PHPの「値」には2つの属性があります。
「中身」と「型」です。

「false」と「0」と「null」は中身は0ですが、型が異なります。

false論理型(trueとfalseの2種類のみ)
0整数型(数字)
nullNULL型(NULLのみ)

次の例は、全部数字の「1」ですが型が異なるため、異なる「1」として判断できます。

<?php
$table = array((int)1, (string)1, (float)1);

foreach($table AS $value)
{
	if ($value === (int)1)
	{
		echo " 数字 ";
	}
	else if ($value === (string)1)
	{
		echo " 文字 ";
	}
	else if ($value === (float)1)
	{
		echo " 浮動小数点 ";
	}
}

?>

すべて数字の1ですが、それぞれ異なる結果になります。

条件式を3文字にすると型を含めて比較してくれる

==や != は、中身だけを比較するのに対し、===や !==は中身と型を比較します
そのため、判別がつくのです。

逆に同じ値でも違うという判定になる可能性もあります。
例えば、trueかfalseだけを判定したい場合は 3文字にしたほうがより精密ですが、数字を比較する場合は2文字にしたほうが型による誤動作を防げます。

要はケースバイケースで使うのがよいと言えます。

今回も新しい学びがありました。
本記事がまたお役に立てば幸いです。

モバイルバージョンを終了