【PHP】FastRouteによるURLルーティング
URLルーティングにFastRouteを利用する
PHPのURLルーティング用ライブラリ、 FastRouteの利用方法を紹介します。
github
nikic/FastRoute
環境: PHP 8.1.15、 nikic/FastRoute 1.3.0
FastRouteの利用準備
composerを利用してプロジェクトにFastRouteのパッケージをインストールします。
composer require nikic/fast-route
FastRouteはフロントコントローラの仕組みを採用しているので .htaccessをドキュメントルート配下に作成します。
.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]
フロントコントローラの概要については以下の記事を参照ください。
基本的なURLルーティング処理
FastRouteの利用準備が出来たら、URLルーティング処理をアプリケーションに実装します。
以下サンプルでは簡易な利用手順として、index.php内でFastRouteによるルーティング処理を直に行なっています。
(プロジェクト構成)
.
├── app
│ ├── composer.json
│ ├── composer.lock
│ └── vendor
└── htdocs
├── .htaccess
└── index.php
index.php
<?php
require __DIR__ . '/../app/vendor/autoload.php';
$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $r) {
$r->addRoute('GET', '/', 'top');
$r->addRoute('GET', '/login/', 'login');
// {id} must be a number (\d+)
$r->addRoute('GET', '/user/{id:\d+}', 'user');
});
// Fetch method and URI from somewhere
$httpMethod = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];
// Strip query string (?foo=bar) and decode URI
if (false !== $pos = strpos($uri, '?')) {
$uri = substr($uri, 0, $pos);
}
$uri = rawurldecode($uri);
$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
switch ($routeInfo[0]) {
case FastRoute\Dispatcher::NOT_FOUND:
http_response_code(404);
echo "404 Not Found";
break;
case FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
$allowedMethods = $routeInfo[1];
http_response_code(405);
echo "405 Method Not Allowed";
break;
case FastRoute\Dispatcher::FOUND:
$handler = $routeInfo[1];
$vars = $routeInfo[2];
if (!empty($vars)) {
// ... call $handler with $vars
echo $handler($vars);
} else {
echo $handler();
}
break;
}
function top()
{
return '<html><h1>top page</h1></html>';
}
function login()
{
return '<html><h1>login page</h1></html>';
}
function user(array $args)
{
$id = $args['id'];
return "<html><h1>user id: $id</h1></html>";
}
こちらのサンプルは、ほとんど公式のgithub上の実装例のままですが、リクエストURLによって実行される関数を振り分ける処理を行なっています。
変数dispatcherを定義している箇所、simpleDispatcherの引数として実行される無名関数内にある、addRouteでリクエストメソッド(GETかPOST)、リクエストのパス、実行する関数を登録します。
それにより、リクエストパスが
/ のとき top
/login/のとき login
/user/{id} のとき user
とそれぞれ、定義された関数が実行されて必要なページを結果として返すようになっています。
ルーティング登録箇所は以下のように直接リクエストメソッドを指定して記述を簡略化することが出来ます。
$r->get('/', 'top');
また実装の中で、受け付けたリクエストが登録済みのルーティングに存在しない場合は404、定義されているリクエストメソッドと一致しない場合は405を、それぞれステータスコードとメッセージを返しています。