====== リクエストルーター - 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}"; } \\