PHPライブラリ・AltoRouterでフレームワーク的なルーティングを実装する
フレームワークを使うほどじゃない小規模プロジェクトで、Laravel的ななルーティングを実装したくて、PHPライブラリ・AltoRouterを使ってみたのでまとめです。
公開日:2019年4月4日
やりたかったこと
非フレームワークでピュアなPHPでサイトを作る際に、Laravelのようにルーティングを設定ファイルに書くだけでルートとコントローラーをつないで処理する機能を実装したいと思い、ライブラリを探していました。
Route::get('hello/', 'App\Controllers\helloController@goodmorning');
こういうやつですね。
AltoRouterとは
PHPのルーティングライブラリです。
Githubでソースコードが公開されていて、MITライセンスで自由に使うことができます。
AltoRouterをインストール
Composrerが楽なので、Composerでインストールしました。
composer requier altorouter/altorouter
ソースコードをGithubからダウンロードして、ソースコードをrequireしてもOKです。
dannyvankooten/AltoRouter | Github
ライブラリ本体は、ルートディレクトリのAltoRouter.phpです。このファイルを使いたいPHPファイルでrequireします。
require 'AltoRouter.php';
AltoRouterを使ってみる
ファイル構成
今回のテストでは、下記のようなファイル構成になります。
- index.php
- Core.php
- vendor
- .htaccess
AltoRouterはComposerでインストールしている前提とします。
まずは.htaccessを設定
AltoRouterは、すべてをindex.phpに集約してURLを変数化してマッチさせる方式になっているので、.htaccessの設定が必要です。Apache、Nginxで設定してもOKです。
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
ルーティングの仕組みを書く
続いて、ルーティングの仕組みを書きます。
<?php
require_once __DIR__ . '/../vendor/autoload.php';
$router = new AltoRouter();
$router->map('GET|POST','/',
'App\TopController::index',
'home'
);
$match = $router->match();
if( is_array($match) && is_callable( $match['target'] ) ) {
$params = explode("::", $match['target']);
$action = new $params[0]();
call_user_func_array(array($action, $params[1]) , $match['params']);
} else {
header( $_SERVER["SERVER_PROTOCOL"] . ' 404 Not Found');
}
AltorouterでLaravel的なクラス名ルーティングをする方法
上記のコードはルート設定を含んでいますが、別ファイル化してもOKです。
注意したいのは、AltoRouterライブラリを読み込んだだけでは、何も動きません。AltoRouterがやっているのは、ルーティングのマッチ判定だけなので、
$match = $router->match();
で、リクエストに対してマッチ判定を行って「$match」に結果を格納してAltoRouterの役割としては終了です。
これだけではルーティングが出来ないので、
if( is_array($match) && is_callable( $match['target'] ) ) {
$params = explode("::", $match['target']);
$action = new $params[0]();
call_user_func_array(array($action, $params[1]) , $match['params']);
} else {
header( $_SERVER["SERVER_PROTOCOL"] . ' 404 Not Found');
}
で、コントローラー:メソッドを呼び出すようにします。
呼び出せるメソッドだったらcall_user_func_arrayでメソッドを実行して、ダメだったら404エラーを返すようにしてます。
index.phpの例
index.phpは先程のCore.phpを呼び出すだけでOKです。
<?PHP
reqire_once('Core.php');
これでAltoRouterでルーティングされるようになりました。
AltoRouterのルーティングの書き方
続いて、AltoRouterでのルーティングの書き方を見ていきます。
ルーティングの基本
もっともシンプルなのは、PHPファイルを読み込むケースですが、その場合は、
$router->map( 'GET', '/', function() {
require __DIR__ . '/views/home.php';
});
これでOKです。
ルーティングの各変数を知る
各変数は、
$router->map(
'GET|POST', # リクエストメソッド
'/[a:siteCode]/',
# マッチパターン
'App\LogsController::writeLog',
# アクション
'writeLog'
# alias(省略可能)
);
となっています。
アクション部分は、先程の例のようにそのままメソッドを展開させてもOKです。
最後の変数はaliasで、ここを設定しておくと、
$router->generate('home');
でURLを発行してくれます。このあたりもLaravelっぽいですね。
マッチパターンを知る
マッチパターンは、「パターン:変数名」のルールで書きます。
パターンは、下記のようになっています。
* // Match all request URIs
[i] // Match an integer
[i:id] // Match an integer as 'id'
[a:action] // Match alphanumeric characters as 'action'
[h:key] // Match hexadecimal characters as 'key'
[:action] // Match anything up to the next / or end of the URI as 'action'
[create|edit:action] // Match either 'create' or 'edit' as 'action'
[*] // Catch all (lazy, stops at the next trailing slash)
[*:trailing] // Catch all as 'trailing' (lazy)
[**:trailing] // Catch all (possessive - will match the rest of the URI)
.[:format]? // Match an optional parameter 'format' - a / or . before the block is also optional
'i' => '[0-9]++'
'a' => '[0-9A-Za-z]++'
'h' => '[0-9A-Fa-f]++'
'*' => '.+?'
'**' => '.++'
'' => '[^/\.]++'
よく使うところでいうと、「a(英数字)」「i(数字)」でしょうか。正規表現も使えるので、比較的柔軟にマッチパターンを作れます。
PHPライブラリ・AltoRouterでフレームワーク的なルーティングを実装する方法をみてきました。概ねLaravelに近いルーティングが実装できたと思います。
ルーティングだけならピュアPHP + AltoRouterでも十分ですね。
新着ノート
-
Gitlabの2段階認証下でコンテナレジストリにPushする方法
gitlab
公開日:2020年12月23日
-
HUGO
公開日:2020年4月27日
新着コード
-
cURLでCloudflare APIでキャッシュを削除する
cloudflare
公開日:2020年5月1日
-
iOS Safariでselectを含む要素にoverflow-y:scrollすると横にスクロールする時の対応
iOS
公開日:2020年4月15日