0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PHPで入力値の空判定でemptyを使うと、"0" がempty判定されてしまうので注意

0
Last updated at Posted at 2026-09-07

はじめに

入力値が空かどうかの判定に empty() を使うと、0 の1文字が空として扱われます。
0 を入力したのに、未入力と同じ扱いになります。

この記事では、空判定に使う書き方が 0 をどう扱うのかと、空判定をどう書けばよいのかを扱います。

環境: PHP 8.5.9

入力値の空判定に empty() を使うと 0 が空になる

入力された値があればそれを使い、無ければ既定値を使うコードです。

/**
 * 使う値を決める
 * 入力された値 → 既定値、の順で使う
 * @param  array $config
 * @return string
 */
function resolveValue(array $config): string
{
    if (!empty($config['userValue'])) {
        return $config['userValue'];
    }

    return $config['defaultValue'];
}

abc を渡せばそのまま返りますが、0 を渡すと既定値が返ります。

var_dump(resolveValue(['userValue' => 'abc', 'defaultValue' => '既定値'])); // string(3) "abc"
var_dump(resolveValue(['userValue' => '0',   'defaultValue' => '既定値'])); // string(9) "既定値"

empty() と三項演算子の短縮形は、同じ判定をしている

empty() だけの問題ではありません。
空判定によく使う三項演算子の短縮形 ?: も、"0" を空と判定します。

empty() は "0" に対して true を返す

PHPマニュアル > empty には、戻り値について次のように書かれています。

var が存在しない、 または空や0の値が設定されている場合、 つまり boolean のコンテキストで false と見なされる場合、 true を返します。

文字列の "0" は、booleanコンテキストで false と評価されます。
そのため empty() は true を返します。

var_dump(empty('0'));     // bool(true)
var_dump(empty('abc'));   // bool(false)

三項演算子の短縮形 ?: は "0" のとき右辺を返す

PHPマニュアル > 比較演算子 には、三項演算子の短縮形について次のように書かれています。

三項演算子のまんなかの部分をなくすこともできます。 式 expr1 ?: expr3 の結果は、expr1 が true と同等の場合は expr1、 それ以外の場合は expr3 となります。 この場合、expr1 は一度だけ評価されます。

「true と同等」かどうかの判定は、empty() と同じfalsy判定です。
そのため左辺が "0" のときは、右辺が返ります。

var_dump('0' ?: '既定値');     // string(9) "既定値"
var_dump('abc' ?: '既定値');   // string(3) "abc"

どちらも、書き方は違っても判定しているものは同じです。
値があるかどうかを確かめたつもりで、booleanに変換したときに真かどうかを確かめていることになります。

空判定は空文字との比較で書く

判定したいのは未入力かどうかです。
falsy判定をやめて、空文字との比較に変えます。
キーが存在しない場合に備えて、?? で空文字を補ってから比較します。

修正後のコードです。

function resolveValue(array $config): string
{
    // 「0」の1文字も入力できるため、empty()や三項演算子の短縮形では未入力と区別できない
    if (($config['userValue'] ?? '') !== '') {
        return $config['userValue'];
    }

    return $config['defaultValue'];
}
var_dump(resolveValue(['userValue' => '0', 'defaultValue' => '既定値'])); // string(1) "0"

まとめ

  • 入力値の空判定に empty() を使うと、0 の1文字が未入力と同じ扱いになります
  • 三項演算子の短縮形 ?: も同じfalsy判定なので、左辺が "0" のときは右辺の値になります
  • 未入力かどうかを判定したいのであれば、falsy判定ではなく null や空文字との比較で書きます

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?