---
title: "ルーティング"
description: "NibiruがURLをコントローラー、アクション、パラメーターにマッピングする方法——SEOフレンドリーなURL形式も含む。"
---

Nibiruのルーティングは**規約に基づく**もので、特殊なケースのために`settings.<env>.ini`からオプションで正規表現を使用したルートを設定できます。大きなルートファイルを維持する必要はありません。

## デフォルトの規約
```
/<controller>/<action>/<param1>/<param2>/...
```
例：

| URL | コントローラー | アクション | $_REQUEST |
|---|---|---|---|
| `/` | `indexController` | (なし) | — |
| `/products` | `productsController` | (なし) | — |
| `/products/detail` | `productsController` | `detailAction` | — |
| `/products/detail/42` | `productsController` | `detailAction` | `id => 42` |
| `/users/edit/42` | `usersController` | `editAction` | `id => 42` |

`_action` がない場合、のみ `navigationAction()` と `pageAction()` が実行されます。`_action` がある場合、指定されたアクションがその間に実行されます。

## SEO URL

Nibiru は、どの設定も不要で SEO フレンドリーな URL を自動検出します。パターン：
```
/<controller>/<slug>/<numeric-id>
```
もし2番目のセグメントがコントローラーのメソッド名でない場合、3番目のセグメントが数値である場合、Nibiruは内部的にリクエストを書き換えます。
```
/<controller>/detail/?id=<numeric-id>&slug=<slug>
```
したがって、URL `/maschine/marduk-gold-plating/42` は `maschineController::detailAction()` に到達し、`$_REQUEST['id'] === '42'` かつ `$_REQUEST['slug'] === 'marduk-gold-plating'` となります。これは、プロダクション E-コマースサイト `prod.maschinen-stockert.de` がカスタムルーターなしでクリーンな URL を生成するのと同じ方法です。

## パラメータの読み取り

アクションセグメント以降は、位置によってペアリングされた `$_REQUEST` キーになります。
```php
// /users/edit/42  →  $_REQUEST['id'] = '42'
public function editAction() {
    $id = (int) ($_REQUEST['id'] ?? 0);
    // ...
}
```
数値的または名前付きパラメータ以外の場合、クエリ文字列を使用することをお勧めします。
```
/users/search?q=marduk&page=2
```
## カスタムルートをINIで設定する

`[NIBIRU_ROUTING]` セクションは、`settings.<env>.ini` で正規表現の URL パターンをコントローラー/アクションのペアと名前付きパラメータにマッピングできます。
```ini
[NIBIRU_ROUTING]
; Map /api/v1/products/42 to apiController::productsAction with id=42
api.v1.products.pattern    = "^/api/v1/products/(\d+)$"
api.v1.products.controller = "api"
api.v1.products.action     = "products"
api.v1.products.params[]   = "id"
```
パターンに一致するURLの場合、キャプチャーグループは順番に名前付きの `params[]` キー（`$_REQUEST` エントリ）に割り当てられます。

## ルーティングヘルパー
```php
Router::getInstance()->currentPage();   // 'products'
Router::getInstance()->tplName();       // 'products'  (controller stem for templates)
Router::getInstance()->getController(); // alias for currentPage()
```
これらはコントローラーとテンプレート内で役立ちます：
```smarty
<a href="/products" class="{if Router::currentPage() == 'products'}active{/if}">
  Products
</a>
```
(Smartyでは、Smartyプラグインまたは事前に割り当てられた変数を使用します；ヘルパー自体はPHP用です。)

## 転送

フレームワークレベルでリダイレクトする（適切なHTTPヘッダーを設定し、終了する）：
```php
View::forwardTo('/login');
```
JSON レスポンスの場合 (`Content-Type: application/json` を設定します):
```php
View::forwardToJsonHeader();
View::assign(['data' => ['ok' => true]]);
```
このパターンは、プロダクションのAPIエンドポイントで重く使用されています — `data.maschinen-stockert.de` の `apiController` をご覧ください。

## ページネーションのURL

Nibiruの[pagination](/core/pagination/)は、次の形式のURLを期待しています：
```
/<controller>/<action>/page/<N>
```
`Pageination` クラスは、末尾の `page/N` 段階を解析するため、それを保持する任意のルート形式で構いません。

## 末尾のスラッシュと大文字小文字

URLは**大文字小文字を区別して**マッチされます。`/Users/edit`と`/users/edit`は異なるコントローラーにヒットします（後者は存在し、前者は404エラーになります）。末尾のスラッシュは許容されます。

## 一般的な落とし穴

- **アクションとSEO URLの衝突。** メソッドを `aboutAction()` に名付け、`/products/about/42` をSEO URLとして使用しようとすると、SEOリライトは *トリガーされません* 。なぜなら、`about` が既知のアクションであるためです。アクション名と衝突しないスラッグを選択してください。
- **`_action` のないアクション。** `/products/detail/` だけを入力しても `detailAction()` を呼び出しません — `_action` は必須です。URLに少なくとも2つのセグメントがある場合、ディスパッチャーは自動的にこれを行いますが、クエリ文字列が削除された場合は行われません。
- **`index` はルートコントローラーです。** `/` → `indexController` 。別途の "ホーム" ルートはありません。
