
Cake2から4への移行作業時に、つい見落としがちなものに TypeError が挙げられます。
Cake2で実装されたメソッドをCake4メソッドとして移行する際に期待することは、「Cake2と同じ動作をするかどうか」というのを本筋で考えると思います。結果としては同じ動作ができれば移行完了になります。
ですが、実は細かく debug などでデバッグすると、データ構造の違いであったり、微妙な差異が原因で意図せずエラーに落ちたり、メソッドの利用箇所が多ければ、その影響範囲を考慮する必要があるので要注意です。
とくに異常系は見落としやすく、Cake2では許容されていても、Cake4では許容されなくなるケースもあります。本記事の TypeError による InvalidArgumentException() もその中の一つです。
たとえば、URLに意図せず文字列が混じっていた場合でも、Cake2ならスルーされていた挙動が、Cake4ではサーバーエラーになったりします。
Cake2: シンプルな実装例
public function getArticle($id) {
$Article = $this->find('first', array(
'conditions' => array(
'id' => $id,
),
));
if(empty($Article)) {
throw new NotFoundException();
}
return $Article;
}
Cake4: 上記例を移行した形
public function getArticle($id): ?array
{
$Article = $this->find()
->where(['id' => (int)$id]) // カラムの型にキャストすることで、不正な文字列が送られてきてもTypeErrorを避けることができる。レビュー時にも見落としやすい。
->first();
if (empty($Article)) {
throw new NotFoundException();
}
return $Article;
}
上記例の重要なポイントとしては、返り値型指定に null 許容をしている箇所と、idの引数に型キャストをして、文字列があった場合は強制的にINT型にすることで TypeError を避けています。
返り値型指定も null を許容しておかないと、レコードが取得できなかった場合に TypeError を引き起こします。このあたり、php7以降は結構型に関しても厳密になりつつあるので気をつけたいところでがあります。※別に返り値型を定義しない作戦もあるけど(事故は減らせるという意味では)
■ PHP: TypeError
https://www.php.net/manual/ja/class.typeerror.php
■ PHP: InvalidArgument
https://www.php.net/manual/ja/class.invalidargumentexception.php
■ Cakephp: InvalidAugumentException
https://api.cakephp.org/4.4/class-Cake.Cache.InvalidArgumentException.html