PHP7.2からのcount()の挙動に悩んだ

概要

PHPのバージョンを7.0(7.0.15)から7.2(latest)に上げたときに起きた問題

エラーの内容

php7.2 count でググればたくさん出てくるので、細かいことは省略するが、 count()の仕様変更により、配列などCountable なものではないとエラーを返すようになった。

PHP Warning:  count(): Parameter must be an array or an object that implements Countable

PHP7.0での挙動

いくつか試してみた。思いつく限り。

var_dump(count(''));
// →int(1)
var_dump(count('hoge'));
// →int(1)
var_dump(count('0'));
// →int(1)
var_dump(count('1'));
// →int(1)
var_dump(count('2'));
// →int(1)
var_dump(count(0));
// →int(1)
var_dump(count(1));
// →int(1)
var_dump(count(2));
// →int(1)
var_dump(count([]));
// →int(0)
var_dump(count(['']));
// →int(1)
var_dump(count(['','']));
// →int(2)
var_dump(count(['1','']));
// →int(2)
var_dump(count(null));
// →int(0)
var_dump(count(true));
// →int(1)
var_dump(count(false));
// →int(1)

やりたかったこと

誰かが作った既存のメソッドがあって、

public function getHoge($fuga)
{
    return count($fuga->getPiyo());
}

これのI/Fを担保したかった。影響範囲がよくわからないから。

どうしたのか

上記の挙動を見る限り、

  • 配列かどうか
  • NULLかどうか

の判定で済みそうだと思ったので、いったんは以下にしてみる。 本当はもっと厳密にあらゆることを想定する必要があるはず。

public function getHoge($fuga)
{
    if (is_array($fuga->getPiyo())) {
        return count($fuga->getPiyo());
    }

   return is_null($fuga->getPiyo()) ? 0 : 1;
}

まとめ

そもそもなぜこのエラーに出くわしたかというと、新規で開発をしてたときに、過去のテストコードが通らなくなったから。

要はテストコードって大事だよね、という話なのかもしれない。