Debug My Life.

いろいろデバッグをがんばるブログ。

php 7.2(Laravel)のcount()仕様変更でテーブル取得後の判定を修正

最近phpのバージョンを7.2に変更したら、count()関数の仕様が変わってしまって、いろいろ修正しなくてはいけなくなった。
今まで普通に動いていた箇所が、以下のようなエラーが出るようになった。

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

マニュアルページを確認すると、以下のようにあった。

countable ではない型に対して count() (およびそのエイリアスである sizeof()) を使ったときに E_WARNING が発生するようになりました。

PHP: 下位互換性のない変更点 - Manual

以下のようにLaravelでテーブルからのレコード取得後の件数があるかどうかで、分岐処理で戻り値を返すような処理をcount()関数を使って書いていることが多かったので、それらをすべて修正する羽目になった・・・。

$room = TrnRoom::where('room_name', $room_name)
		->where('venue_id', $this->target_venue_id)
		->where('delete_flag', false)
		->first();

if(count($room) > 0){
	return $room;
}else{
	return false;
}

修正後はcount()の部分をempty()に変更が基本。

$room = TrnRoom::where('room_name', $room_name)
		->where('venue_id', $this->target_venue_id)
		->where('delete_flag', false)
		->first();

if(!empty($room)){
	return $room;
}else{
	return false;
}

しかし、0件判定でemptyが有効なのはEloquentでテーブル取得処理を->first()で実行したときだが、->get()を使用した場合は0件でもempty()がfalse判定になるので注意。->get()で0件の場合は、コレクション型で中身なしのものが戻るので、その場合はempty()の判定がtrueになる。->first()の0件の場合はnullなので、emptyがtrue判定になる(->first(), ->get()の戻り値の型を意識しなくてもcount()で判定できていたので、count()をよく書くことになっていたのだった・・・)。

よって、->get()で取得する場合は、以下のような修正で対応した。

$room = TrnRoom::where('room_name', $room_name)
		->where('venue_id', $this->target_venue_id)
		->where('delete_flag', false)
		->get();

if(room->isNotEmpty()){
	return $room;
}else{
	return false;
}

LaravelのコレクションにはisEmpty(), isNotEmpty()メソッドが使えるので、どちらかを使うとよい。
単純に件数が存在するかどうかを判定するにはisNotEmpty()でtrue判定を得た方がわかりやすい。
件数ありの場合でisEmpty()の場合をtrueにする場合は、!で反転する必要があるが、若干わかりにくい。

コレクション 5.6 Laravel

今年からブログを週1回は更新するといってまた放置気味になったので、よいネタができたと思っておこう。