これも今更な話なのだが、いままでPHPである連想配列$fooに'bar'というキーが存在するかを調べるのに、
if (isset($foo['bar'])) {
// キーが存在した場合の処理
}
とやっていたんだけれど、厳密にはこれじゃだめだったんだね…。
説明
bool isset ( mixed $var [, mixed $... ] )
変数がセットされており、それが NULL でないことを調べます。
変数が、 unset() により割当を解除された場合、 何も値が設定されていない状態になります。 NULLに設定されている変数を調べた場合、 isset() はFALSEを返します。 NULLバイト("\0")はPHPの定数 NULLと等価ではないことにも注意してください。
PHP: isset - Manual![]()
期待していたのは、「割り当て解除時」にのみ false が返り、他は true というものだったのだが、違ったわけだ。NULL のみ特別扱い(''や 0 や "\0" がセットされていたら true)。
issetって名前なんだから、NULLがセットされていても true 返せよ……マニュアルに書いてある仕様通り、と言われれば、ぐうの音も出ないが。
ちなみに、未割当の(解除された)変数へのポインタを代入した参照渡しをした変数を引数にしても false が返る。
$b=1; unset($b); $a=&$b; var_dump(isset($a)); // bool(false) $b=null; var_dump(isset($a)); // bool(false) $b=1; var_dump(isset($a)); // bool(true)
というか、これに類似した処理を行っている箇所の動きがおかしかったので、上記の事に気が付いた。
ということで、想定している動作をさせようとすると、
if (array_key_exists('bar', $foo)) { // キーが存在した場合の処理 }
と書く必要がある、ということ。