ルーティング

デフォルトルーティングルール

webmanのデフォルトルーティングルールは http://127.0.0.1:8787/{コントローラ}/{アクション} です。

デフォルトコントローラは app\controller\IndexController、デフォルトアクションは index です。

例えばアクセスする場合:

  • http://127.0.0.1:8787 はデフォルトで app\controller\IndexController クラスの index メソッドにアクセスします
  • http://127.0.0.1:8787/foo はデフォルトで app\controller\FooController クラスの index メソッドにアクセスします
  • http://127.0.0.1:8787/foo/test はデフォルトで app\controller\FooController クラスの test メソッドにアクセスします
  • http://127.0.0.1:8787/admin/foo/test はデフォルトで app\admin\controller\FooController クラスの test メソッドにアクセスします (参考:複数アプリ)

さらに、webmanは1.4からより複雑なデフォルトルーティングをサポートしています。例えば:

app
├── admin
│   └── v1
│       └── v2
│           └── v3
│               └── controller
│                   └── IndexController.php
└── controller
    ├── v1
    │   └── IndexController.php
    └── v2
        └── v3
            └── IndexController.php

特定のリクエストルートを変更したい場合は、設定ファイル config/route.php を変更してください。

デフォルトルーティングを無効にしたい場合は、設定ファイル config/route.php の最後の行に以下の設定を追加します:

Route::disableDefaultRoute();

クロージャルート

config/route.php に以下のルートコードを追加します:

use support\Request;
Route::any('/test', function (Request $request) {
    return response('test');
});

注意
クロージャー関数は任意のコントローラに属さないため、$request->app $request->controller $request->action はすべて空の文字列です。

アクセス先が http://127.0.0.1:8787/test の場合、test という文字列が返されます。

注意
ルートパスは必ず / で始まる必要があります。例えば:

use support\Request;
// 誤った使い方
Route::any('test', function (Request $request) {
    return response('test');
});

// 正しい使い方
Route::any('/test', function (Request $request) {
    return response('test');
});

クラスルート

config/route.php に以下のルートコードを追加します:

Route::any('/testclass', [app\controller\IndexController::class, 'test']);

アクセス先が http://127.0.0.1:8787/testclass の場合、app\controller\IndexController クラスの test メソッドの返り値が返されます。

ルートパラメーター

ルートにパラメーターがある場合、{key} を使用してマッチさせ、マッチした結果は対応するコントローラメソッドのパラメーターに渡されます(2番目のパラメータから順に渡されます)。例えば:

// /user/123 /user/abc にマッチ
Route::any('/user/{id}', [app\controller\UserController::class, 'get']);
namespace app\controller;
use support\Request;

class UserController
{
    public function get(Request $request, $id)
    {
        return response('受け取ったパラメータ'.$id);
    }
}

さらに例:

use support\Request;
// /user/123 にマッチし、/user/abc にはマッチしない
Route::any('/user/{id:\d+}', function (Request $request, $id) {
    return response($id);
});

// /user/foobar にマッチし、/user/foo/bar にはマッチしない
Route::any('/user/{name}', function (Request $request, $name) {
   return response($name);
});

// /user /user/123 および /user/abc にマッチします   []はオプションを示します
Route::any('/user[/{name}]', function (Request $request, $name = null) {
   return response($name ?? 'tom');
});

// 任意の /user/ で始まるリクエストにマッチ
Route::any('/user/[{path:.+}]', function (Request $request) {
    return $request->path();
});

// すべてのoptionsリクエストにマッチ   :の後に正規表現を記入します。この命名パラメータの正規ルールを示します
Route::options('[{path:.+}]', function () {
    return response('');
});

進んだ使い方のまとめ

[] 構文は Webman ルーティングで主にオプションのパス部分を処理したり、動的ルーティングをマッチさせたりするために使用され、ルーティングに対してより複雑なパス構造とマッチングルールを定義できるようにします。

: は正規表現を指定するために使用されます

ルートグループ

時々、ルートに大量の同じ接頭辞が含まれている場合があります。この場合、ルートグループを使用して定義を簡略化できます。例えば:

Route::group('/blog', function () {
   Route::any('/create', function (Request $request) {return response('create');});
   Route::any('/edit', function (Request $request) {return response('edit');});
   Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
});

次のように等価です:

Route::any('/blog/create', function (Request $request) {return response('create');});
Route::any('/blog/edit', function (Request $request) {return response('edit');});
Route::any('/blog/view/{id}', function (Request $request, $id) {return response("view $id");});

グループのネスト使用:

Route::group('/blog', function () {
   Route::group('/v1', function () {
      Route::any('/create', function (Request $request) {return response('create');});
      Route::any('/edit', function (Request $request) {return response('edit');});
      Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
   });  
});

ルートミドルウェア

特定のルートまたはルートグループにミドルウェアを設定できます。
例えば:

Route::any('/admin', [app\admin\controller\IndexController::class, 'index'])->middleware([
    app\middleware\MiddlewareA::class,
    app\middleware\MiddlewareB::class,
]);

Route::group('/blog', function () {
   Route::any('/create', function () {return response('create');});
   Route::any('/edit', function () {return response('edit');});
   Route::any('/view/{id}', function ($request, $id) {response("view $id");});
})->middleware([
    app\middleware\MiddlewareA::class,
    app\middleware\MiddlewareB::class,
]);
# 誤った使用例 (webman-framework >= 1.5.7 の場合はこの使い方が有効)
Route::group('/blog', function () {
   Route::group('/v1', function () {
      Route::any('/create', function (Request $request) {return response('create');});
      Route::any('/edit', function (Request $request) {return response('edit');});
      Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
   });  
})->middleware([
    app\middleware\MiddlewareA::class,
    app\middleware\MiddlewareB::class,
]);
# 正しい使用例
Route::group('/blog', function () {
   Route::group('/v1', function () {
      Route::any('/create', function (Request $request) {return response('create');});
      Route::any('/edit', function (Request $request) {return response('edit');});
      Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
   })->middleware([
        app\middleware\MiddlewareA::class,
        app\middleware\MiddlewareB::class,
    ]);  
});

リソースルーティング

Route::resource('/test', app\controller\IndexController::class);

//指定されたリソースルーティング
Route::resource('/test', app\controller\IndexController::class, ['index','create']);

//非定義型リソースルーティング
// notify へのアクセスアドレスは any 型ルート /test/notify または /test/notify/{id} のどちらでも可能 routeName は test.notify
Route::resource('/test', app\controller\IndexController::class, ['index','create','notify']);
動詞 URI アクション ルート名
GET /test index test.index
GET /test/create create test.create
POST /test store test.store
GET /test/{id} show test.show
GET /test/{id}/edit edit test.edit
PUT /test/{id} update test.update
DELETE /test/{id} destroy test.destroy
PUT /test/{id}/recovery recovery test.recovery

URL生成

注意
現時点では、groupネストのルート生成URLはサポートされていません

例えばルート:

Route::any('/blog/{id}', [app\controller\BlogController::class, 'view'])->name('blog.view');

このルートのURLを生成するには、次の方法を使用できます。

route('blog.view', ['id' => 100]); // 結果は /blog/100

ビューでルートのURLを使用する場合は、この方法を使用できます。これにより、ルーティングルールがどのように変更されても、URLが自動的に生成されるため、ルートアドレスの調整による視覚ファイルの大量変更を避けることができます。

ルート情報の取得

$request->route オブジェクトを使用して、現在のリクエストルート情報を取得できます。例えば:

$route = $request->route; // $route = request()->route; と同等
if ($route) {
    var_export($route->getPath());
    var_export($route->getMethods());
    var_export($route->getName());
    var_export($route->getMiddleware());
    var_export($route->getCallback());
    var_export($route->param());
}

注意
現在のリクエストが config/route.php に設定された任意のルートに一致しなかった場合、$request->route は null になります。このため、デフォルトルーティング時には $request->route は null になります。

404処理

ルートが見つからない場合、デフォルトで404ステータスコードが返され、404関連の内容が出力されます。

開発者がルートが見つからないときのビジネスプロセスに介入したい場合は、webmanが提供するフォールバックルート Route::fallback($callback) メソッドを使用できます。例えば、以下のコードロジックは、ルートが見つからなかった場合にホームページにリダイレクトします。

Route::fallback(function(){
    return redirect('/');
});

また、ルートが存在しない場合にJSONデータを返すこともできます。これは、webmanがAPIインターフェースとして使用される場合に非常に便利です。

Route::fallback(function(){
    return json(['code' => 404, 'msg' => '404 not found']);
});

404にミドルウェアを追加する

デフォルトの404リクエストはミドルウェアを通過しません。404リクエストにミドルウェアを追加する必要がある場合は、以下のコードを参照してください。

Route::fallback(function(){
    return json(['code' => 404, 'msg' => '404 not found']);
})->middleware([
    app\middleware\MiddlewareA::class,
    app\middleware\MiddlewareB::class,
]);

関連リンク:カスタム404 500ページ

デフォルトルートを無効にする

// メインプロジェクトのデフォルトルートを無効にし、アプリケーションプラグインには影響しません
Route::disableDefaultRoute();
// メインプロジェクトのadminアプリケーションのルートを無効にし、アプリケーションプラグインには影響しません
Route::disableDefaultRoute('', 'admin');
// fooプラグインのデフォルトルートを無効にし、メインプロジェクトには影響しません
Route::disableDefaultRoute('foo');
// fooプラグインのadminアプリケーションのデフォルトルートを無効にし、メインプロジェクトには影響しません
Route::disableDefaultRoute('foo', 'admin');
// コントローラ [\app\controller\IndexController::class, 'index'] のデフォルトルートを無効にします
Route::disableDefaultRoute([\app\controller\IndexController::class, 'index']);

注釈でデフォルトルートを無効にする

注釈を通じて特定のコントローラのデフォルトルートを無効にすることができます。例えば:

namespace app\controller;
use support\annotation\DisableDefaultRoute;

#[DisableDefaultRoute]
class IndexController
{
    public function index()
    {
        return 'index';
    }
}

同様に、注釈を通じて特定のコントローラのデフォルトルートを無効にすることもできます。例えば:

namespace app\controller;
use support\annotation\DisableDefaultRoute;

class IndexController
{
    #[DisableDefaultRoute]
    public function index()
    {
        return 'index';
    }
}

ルートインターフェース

// $uriの任意のメソッドリクエストのルートを設定
Route::any($uri, $callback);
// $uriのgetリクエストのルートを設定
Route::get($uri, $callback);
// $uriのpostリクエストのルートを設定
Route::post($uri, $callback);
// $uriのputリクエストのルートを設定
Route::put($uri, $callback);
// $uriのpatchリクエストのルートを設定
Route::patch($uri, $callback);
// $uriのdeleteリクエストのルートを設定
Route::delete($uri, $callback);
// $uriのheadリクエストのルートを設定
Route::head($uri, $callback);
// $uriのoptionsリクエストのルートを設定
Route::options($uri, $callback);
// 複数のリクエストタイプのルートを同時に設定
Route::add(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'], $uri, $callback);
// ルートグループ
Route::group($path, $callback);
// リソースルート
Route::resource($path, $callback, [$options]);
// ルートを無効にする
Route::disableDefaultRoute($plugin = '');
// フォールバックルート、デフォルトのルートを設定
Route::fallback($callback, $plugin = '');
// すべてのルート情報を取得
Route::getRoutes();

もしuriに対応するルートがなく(デフォルトルートを含む)、フォールバックルートも設定されていない場合は、404が返されます。

複数のルート設定ファイル

複数のルート設定ファイルを使用してルートを管理したい場合、例えば複数アプリでそれぞれのアプリケーションの下に独自のルート設定がある場合は、外部ファイルを require を通じて読み込むことができます。
例えば config/route.phpでは:

<?php

// adminアプリケーションのルート設定をロードします
require_once app_path('admin/config/route.php');
// apiアプリケーションのルート設定をロードします
require_once app_path('api/config/route.php');