if (empty($someVar)) {
// do something
}
Objectにデータが入っているかどうかを確認するに非常に便利ですね。
でも、こんな書き方が落とし穴あることをご存知ですか?
php docsによると、次のような値は空っぽであるとみなされます。
なんと "0" の文字列なのに、true
を返しています!!
こんな例をみてみましょう
質問: 一日何本のタバコを吸っていますか?
答え(自由書き):0
答えが必須で、"0"を入力したにも関わらず、バリデーションにひっかかれることがわかります。
バリデーションを修正すれば良いと思っていても、もしデータベースの文字列コラムに0が入っていて、予期しない結果が出てくる恐れがあります。
// $answer = "0"
if (!empty($someRecord->answer)) {
doSomethingWithAnswer();
} else {
notAcceptableData();
}
また、もっと酷くなるのは、便利なメソッドだけあって、レガシーコードには全体的に使われていて、影響範囲が非常に壮大に及んでいます。
if (!function_exists('is_blank')) {
function is_blank($value) {
return empty($value) && !is_numeric($value);
}
}
class IsBlankTest extends TestCase
{
public function testIsBlank()
{
$input = '文字列';
$this->assertFalse(!isset($input) || is_blank($input));
$input = '';
$this->assertTrue(!isset($input) || is_blank($input));
$input = ' ';
$this->assertFalse(!isset($input) || is_blank($input));
$input = 0;
$this->assertFalse(!isset($input) || is_blank($input));
$input = 0.0;
$this->assertFalse(!isset($input) || is_blank($input));
$input = '0';
$this->assertFalse(!isset($input) || is_blank($input));
$input = null;
$this->assertTrue(!isset($input) || is_blank($input));
$input = false;
$this->assertTrue(!isset($input) || is_blank($input));
$input = [];
$this->assertTrue(!isset($input) || is_blank($input));
$this->assertTrue(!isset($undefinedVar) || (empty($undefinedVar) && !is_numeric($undefinedVar)));
}
}
// empty()を使う箇所をこの処理にする
if(!isset($someVar) || is_blank($someVar)) {
// do something
}
意外と、PHPにはこんな書き方(emptyを使う)が普及しているようで、意図に反する動きが出るかもしれないので、注意をしましょう。