広告

phpで配列のすべての値がNULLの場合にempty判定をする方法

アイキャッチ プログラミング全般

phpで値が空かどうかを確認するためには、emptyissetis_nullなどを主に使うことになると思いますが、配列では期待通りの判定がうまく行えないケースがあります。

例えば、

$test1 = array(null, null);
$test2 = array('', '');

のように配列内のすべての要素にNULLや空文字がセットされているような場合、empty($test) では falseisset($test)trueis_null($test)false を返し、いずれかの値が存在するような判定として処理してしまう可能性があります。

$foo = null;
$bar = array(null, null);

if (empty($foo)) {
  echo '$fooは空っぽです'
} else {
  echo '$fooは空っぽではありません'
}

if (empty($bar)) {
  echo '$barは空っぽです'
} else {
  echo '$barは空っぽではありません'
}

上記の実行結果は$fooは空っぽです$barは空っぽではありませんとなります。

emptyの仕様としては正しいようなのですが、ちょっとしっくりこない気もします。

配列のすべての要素の値がNULLかどうかを判定する

配列のすべての要素の値がNULLや空文字かどうかを判定するには、以下の一文が使えます。

count(array_filter($arr)) == 0

判定に使用する場合は以下のような感じです。

if (count(array_filter($arr)) == 0) {
  // 配列がすべてNULLか空文字
} else {
  // 配列にNULL以外の要素がある
}

array_filterは、コールバック関数を使って配列の内容をフィルタできる関数ですが、第二引数を渡さずに配列のみを渡すと、デフォルトでempty()関数による各要素のフィルタリングが行われます。

empty()関数はNULLや空文字に対してtrueを返しフィルタ対象となるため、すべての配列要素がNULLであれば、array()の空配列のみが残り、この配列をcount()関数でカウントすることで、配列が空であることを確認できます。

文字列と配列をまとめてemptyかどうかチェックする関数

前述の一文では配列のチェックは可能ですが、文字列変数などを通すことができません。

そもそも対象の変数が配列であれば、初めからこれらのチェック以外の方法を考慮しておく必要があるのですが、文字列変数の判定などと混在していると見落としがちです。

/** @var $foo string|array */
$foo = '';

/** @var $bar string|array */
$bar = array('', NULL);

if (count(array_filter($foo)) == 0) { // エラー
...
}

if (empty($bar)) == 0) { // エラー
...
}

まとめてチェックするような場合は、以下のような関数で配列の判定を行い、それぞれの処理を通すようにすると便利です。

function empty_arr($x) {
  return is_array($x) ? count(array_filter($x)) == 0 : empty($x);
}

こんな感じでまとめてチェックできます。

$foo = '';
$bar = array('', NULL);

if (empty_arr($foo) && empty_arr($bar)) { 
// 文字列$foo、配列$barが両方とも空の場合
...
}

そもそも複数の型の引数を取るような設計に問題があるのですが、そのあたりは置いておいて、関数の返り値や引数でシンプルな1次元配列などを数値や文字列と混在してやり取りしているようなケースでは役立つかもしれません。

コメント

タイトルとURLをコピーしました