====== リクエストルーター - FastRoute ======
Version 1.3 ([[https://github.com/nikic/FastRoute/blob/master/LICENSE|BSD 3-Clause License]])
--- //[[http://www.y2sunlight.com|y2sunlight]] 2020-03-16//
[[basic-library:top|定番ライブラリー に戻る]]
関連記事
* [[basic-library:project|プロジェクトの作成 - Apricot (α版)]]
* [[basic-library:phpdotenv:4.1|環境変数 - phpdotenv]]
* [[basic-library:monolog:2.0|ログ出力 - monolog]]
* [[basic-library:idiorm:1.5|ORマッパー - Idiorm]]
* [[basic-library:bladeone:3.37|テンプレートエンジン - BladeOne]]
* リクエストルーター - FastRoute
* [[basic-library:league-container:3.3|DIコンテナー - League/Container]]
* [[basic-library:valitron:1.4|バリデーター - Valitron]]
* [[basic-library:whoops:2.7|エラーハンドラー - Whoops]]
* [[basic-library:php-debugbar:1.16|デバッグ出力 - php-debugbar]]
リンク
* https://github.com/nikic/FastRoute --- FastRouteの本家
テストプログラムの所在
{Project Folder}\test\fast-route\
----
===== FastRouteについて =====
FastRouteは、PHPコアの開発者の1人でもある [[https://nikic.github.io/aboutMe.html|Nikita]]氏が開発し、[[slim:top|Slim]] フレームワークにも採用されている高速なリクエストリーターです。興味のある方は、なぜ高速であるかを説明するNikita氏の[[http://nikic.github.io/2014/02/18/Fast-request-routing-using-regular-expressions.html|ブログ投稿]]もご覧下さい。
リクエストリーターの選定に当たっては、最近の人気、実行速度、コードの品質から選びました。コードの品質については[[https://php.libhunt.com/|Awesome PHP]]を参考にしました。結果的に次の3つの候補から選びました:
* FastRoute --- https://github.com/nikic/FastRoute
* Klein --- https://github.com/klein/klein.php
* AltoRouter --- https://php.libhunt.com/altorouter-alternatives
機能面を考えるとKleinとAltoRouterも捨てがたい魅力がありましたが、ORマッパーと同じく「兎に角シンプル」と「学習コストが少ない」そして何よりも''高速''という理由でFastRoute を採用することにしました。
===== インストール =====
composer require nikic/fast-route
Using version ^1.3 for nikic/fast-route
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Installing nikic/fast-route (v1.3.0): Downloading (100%)
Writing lock file
Generating autoload files
1 package you are using is looking for funding.
Use the `composer fund` command to find out more!
>Note:
>Eclipse起動中にパッケージを取得した場合は、プロジェクト・エクスプローラー内の[プロジェクト(apricote)]を右クリックして[リフレッシュ]を選択して下さい。また、新しく取得したパッケージのインテリセンスが有効にならない場合は、プロジェクトのビルトまたはクリーン&ビルドを行ってビルドリストの更新を行って下さい。
パッケージの取得が終わると ''composer.json'' の ''require'' に以下が追加されます。
{
"require": {
"nikic/fast-route": "^1.3"
}
}
\\
===== テストプログラム =====
テストフォルダ(''test\'')に フォルダ(''fast-route'') を作成し、そのフォルダに ''.htaccess'' と テストコード(''index.php'')を作成し実行します。''.htaccess''では rewrite を使って ''test\fast-route\'' 下への全ての(実在するディレクトリとファイを除く)リクエストをフロントプロセッサーである ''index.php'' に転送します。
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
以下にテストコード('index.php')を示します。この例は、[[https://github.com/nikic/FastRoute|FastRoute]]サイトの''Usage''にある基本的な使用例を追加・修正したものです。本例の詳細はコード内のコメントをご覧ください。
大まかな流れは「''REQUEST_METHOD'' と ''REQUEST_URI'' でルーティングの定義を行い、それに従い ''dispatch()'' して制御をハンドラーに渡す」と言うものですが、この例ではハンドラーとして(名前のある)関数とクロージャ―(無名関数)を使いました。クラスのインスタンスメソッドの例は、[[apricot::top|Apricot]]をご覧下さい。
addGroup($base, function (FastRoute\RouteCollector $r) use($base)
{
// handlerに関数を指定する
$r->get('/users', 'users'); // 単純なルーティング
$r->get('/user/{id:\d+}', 'user'); // プレースフォルダ(名前:id)
$r->get('/articles/{id:\d+}[/{title}]', 'articles'); // 任意のプレースフォルダ
// handlerにクロージャを指定する
$r->get('[/]', function() use($base)
{
header("Location: " . $base.'/users');
});
});
};
$dispatcher = FastRoute\simpleDispatcher($routes);
// dispatch()に与えるHTTPメソッドとURIを取得
$httpMethod = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];
// dispatch()の妨げになるのでURIの中のクエリパラメータを除去する
// (クエリパラメータは、通常に$_GETで取得できる)
if (false !== ($pos = strpos($uri, '?'))) {
$uri = substr($uri, 0, $pos);
}
// URIの中にクエリパラメータがあるかもしれないのでデコードする
// 例) /hoge/hoge/param/abc%20def
$uri = rawurldecode($uri);
// URIのディスパッチ
$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
switch ($routeInfo[0])
{
case FastRoute\Dispatcher::NOT_FOUND:
// 404 Not Found
break;
case FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
$allowedMethods = $routeInfo[1]; // 許可されているメソッド
// 405 Method Not Allowed
break;
case FastRoute\Dispatcher::FOUND:
$handler = $routeInfo[1]; // ハンドラー 例)user
$params = $routeInfo[2]; // パラメータハッシュ 例)['id'->123]
// ハンドラーを呼び出す
if (is_callable($handler))
{
call_user_func_array($handler, $params);
}
break;
}
// Handler: users
function users()
{
echo "users";
}
// Handler: user
function user(int $id)
{
echo "user({$id})";
}
// Handler: articles
function articles(int $id, string $title=null)
{
echo "articles({$id}){$title}";
}
\\