JavaScriptを有効にしてください

【PHP】関数 empty は罠

 ·  ☕ 2 分で読めます

関数 empty は罠

PHPの関数 empty はとても使いやすく入力値の検査などに使いやすいですがこれが罠なんです。
PHP: empty - Manual

empty の使いやすさ

PHPマニュアルにある empty の説明はこれだけです。

empty — 変数が空であるかどうかを検査する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?php
echo '未定義' . PHP_EOL;
var_dump(empty($hoge));
echo PHP_EOL;

echo '入力なし(文字数0)' . PHP_EOL;
var_dump(empty(''));
echo PHP_EOL;

echo 'NULL' . PHP_EOL;
var_dump(empty(null));
echo PHP_EOL;

echo '値あり' . PHP_EOL;
var_dump(empty('値あり'));
echo PHP_EOL;

出力結果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
未定義
bool(true)

入力なし(文字数0)
bool(true)

NULL
bool(true)

値あり
bool(false)

このように変数が未定義、文字数0や null の場合に true を返します。
わざわざ、変数未定義チェック、null チェック、文字数チェックなどを行う必要がなくとても簡単にチェックをしてくれます。
これだけだと 入力値がないものをに対してtrue を返す関数だと思ってしまいます。

emptyの罠

今度は数値で確認してみます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?php
echo '0' . PHP_EOL;
var_dump(empty(0));
echo PHP_EOL;

echo '1' . PHP_EOL;
var_dump(empty(1)));
echo PHP_EOL;

echo '-1' . PHP_EOL;
var_dump(empty(-1));
echo PHP_EOL;

echo '0000' . PHP_EOL;
var_dump(empty('0000'));
echo PHP_EOL;

出力結果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
0
bool(true)

1
bool(false)

-1
bool(false)

0000
bool(false)

何か挙動が怪しいです。
0true (空)扱いになります。

emptyの罠の原因

empty 関数について、内部で以下のように動いているためです。
表を見ていると false にも true や空の配列に true を返したりします。

empty()
$x = “";true
$x = null;true
var $x;true
$x が未定義NULL
$x = array();true
$x = array(‘a’, ‘b’);false
$x = false;true
$x = true;false
$x = 1;false
$x = 42;false
$x = 0;true
$x = -1;false
$x = “1”;false
$x = “0”;true
$x = “-1”;false
$x = “php”;false
$x = “true”;false
$x = “false”;false

PHP: PHP 型の比較表 - Manual

対策

対策としては empty の表を理解して使用する。

もしくはちゃんと意図した動作を明確に書くことです。
nullチェックでは is_null、文字数チェックでは strlenなど行いたい処理に合わして明確に処理を書いてください。

個人的な見解ですが empty だけだと処理の意図が伝わりづらい事があるので出来るだけ処理を明確に書く方がメンテナンス性が高い気がします。

共有

こぴぺたん
著者
こぴぺたん
Copy & Paste Engineer