AltoRouterがPHP8で動かない問題を修正する

超久しぶりの更新。
別に忙しかったわけではなく、特に書くべきことがなかっただけの話です。

今日のテーマは「AltoRouterがPHP8で動かない問題を修正する」です。
今日この問題に割とハマっていたので、ここに解決法を書いておきます。

この記事を見ている人には説明不要ですが、AltoRouterはシンプルで結構機能もあるルーティングライブラリです。
有名なFastRouteとかに比べるとちょーっと重いみたいなんですが、ま、小規模サイトなら良いでしょう。
で、今回はこのライブラリがPHP8だと動かない(場合がある)ということ。

結論から言えば、AltoRouter自体はPHP8でも(私が見た範囲では)全く問題なく動作します。
問題は、公式サイトにも記載されているdispacherの部分のコードです。

$match = $router->match();
// call closure or throw 404 status
if( is_array($match) && is_callable( $match['target'] ) ) {
	call_user_func_array( $match['target'], $match['params'] ); 
} else {
	// no route was matched
	header( $_SERVER["SERVER_PROTOCOL"] . ' 404 Not Found');
}

で、問題は
is_callableの部分です。PHP8でis_callableの仕様が変更され、クラスの非staticメソッドをClassName::MethodNameで記述した際にfalseが返るようになってしまいました。

なので、ルート指定に
$router->map(‘GET’, ‘/’, ‘Controllers\Welcome::index’);

みたいな書き方をしているとダメなわけです。で、修正したのが、以下。

$match = $router->match();
    
if (!is_array($match)) {
   notfound();
}
$params = explode("::", $match['target']);

if (!class_exists($params[0])) {
   notfound();
}
    
$action = new $params[0]();
    
if (!method_exists($action, $params[1])) {
   notfound();
}

call_user_func_array([$action, $params[1]] , $match['params']);

今まで私はis_callableのために、ClassNameとMethodNameを::で切っていましたが、この際#で分ける記法にしても良いかもしれない。というかそうしよう(::を#に書き換えればいいだけ)。

コメント

タイトルとURLをコピーしました