ルーティングと URL 生成 ======================= Yii のアプリケーションがリクエストされた URL の処理を開始するときに、最初に実行するステップは URL を解析して [ルート](structure-controllers.md#routes) にすることです。次に、リクエストを処理するために、このルートを使って、 対応する [コントローラアクション](structure-controllers.md) のインスタンスが作成されます。 このプロセスの全体が *ルーティング* と呼ばれます。 ルーティングの逆のプロセスが *URL 生成* と呼ばれます。これは、与えられたルートとそれに結び付いたクエリパラメータから URL を生成するものです。生成された URL が後でリクエストされたとき、ルーティングのプロセスは、その URL を解決して、 元のルートとクエリパラメータに戻すことが出来ます。 ルーティングと URL 生成について責任を持つ主要コンポーネントが [[yii\web\UrlManager|URL マネージャ]] であり、`urlManager` アプリケーションコンポーネントとして登録されているものです。[[yii\web\UrlManager|URL マネージャ]] は、入ってくるリクエストを ルートとそれに結び付いたクエリパラメータとして解析するための [[yii\web\UrlManager::parseRequest()|parseRequest()]] メソッドと、 与えられたルートとそれに結び付いたクエリパラメータから URL を生成するための [[yii\web\UrlManager::createUrl()|createUrl()]] メソッドを提供するものです。 アプリケーションコンフィギュレーションの `urlManager` コンポーネントを構成することによって、既存のアプリケーションコードを 修正することなく、任意の URL 形式をアプリケーションに認識させることが出来ます。例えば、`post/view` アクションのための URL を生成するために、次のコードを使うことが出来ます: ```php use yii\helpers\Url; // Url::to() は UrlManager::createUrl() を呼び出して URL を生成します $url = Url::to(['post/view', 'id' => 100]); ``` このコードによって生成される URL は、`urlManager` のコンフィギュレーションに応じて、下記の形式のうちの一つ (またはその他の形式) になります。そしてまた、生成された URL が後でリクエストされたときには、解析されて元のルートとクエリパラメータに戻されます。 ``` /index.php?r=post/view&id=100 /index.php/post/100 /posts/100 ``` ## URL 形式 [[yii\web\UrlManager|URL マネージャ]] は二つの URL 形式をサポートします: デフォルトの URL 形式と、綺麗な URL 形式です。 既定の URL 形式は、`r` というクエリパラメータを使用してルートを表し、通常のクエリパラメータを使用してルートに結び付いたクエリパラメータを表します。 例えば、`/index.php?r=post/view&id=100` という URL は、`post/view` というルートと、`id` というクエリパラメータが 100 であることを表します。 既定の URL 形式は、[[yii\web\UrlManager|URL マネージャ]] についてのコンフィギュレーションを何も必要とせず、 ウェブサーバの設定がどのようなものでも動作します。 綺麗な URL 形式は、エントリスクリプトの名前に続く追加のパスを使用してルートとそれに結び付いたクエリパラメータを表します。 例えば、`/index.php/post/100` という URL の追加のパスは `/post/100` ですが、適切な [[yii\web\UrlManager::rules|URL 規則]] があれば、この URL が `post/view` というルートと `id` というクエリパラメータが 100 であることを表すことが出来ます。 綺麗な URL 形式を使用するためには、URL をどのように表現すべきかという実際の要求に従って、一連の [[yii\web\UrlManager::rules|URL 規則]] を設計する必要があります。 この二つの URL 形式は、[[yii\web\UrlManager|URL マネージャ]] の [[yii\web\UrlManager::enablePrettyUrl|enablePrettyUrl]] プロパティを ON/OFF することによって、他のアプリケーションコードを少しも変えることなく、切り替えることが出来ます。 ## ルーティング ルーティングは二つのステップを含みます。最初のステップでは、入ってくるリクエストが解析されて、ルートとそれに結び付いたクエリパラメータに分解されます。そして、第二のステップでは、解析されたルートに対応する [コントローラアクション](structure-controllers.md) がリクエストを処理するために生成されます。 既定の URL 形式を使っている場合は、リクエストからルートを解析することは、`r` という名前の `GET` クエリパラメータを取得するだけの 簡単なことです。 綺麗な URL 形式を使っている場合は、[[yii\web\UrlManager|URL マネージャ]] が登録されている [[yii\web\UrlManager::rules|URL 規則]] を調べます。合致する規則が見つかれば、リクエストをルートに解決することが出来ます。そういう規則が見つからなかったら、 [[yii\web\NotFoundHttpException]] 例外が投げられます。 いったんリクエストからルートが解析されたら、今度はルートによって特定されるコントローラアクションを生成する番です。 ルートはその中にあるスラッシュによって複数の部分に分けられます。例えば、`site/index` は `site` と `index` に分割されます。 その各部分がモジュール、コントローラ、アクションを参照する ID となります。アプリケーションは、ルートの中の最初の部分から始めて、 下記のステップを踏んで、モジュール (もし有れば)、コントローラ、アクションを生成します。 1. アプリケーションをカレントモジュールとして設定します。 2. カレントモジュールの [[yii\base\Module::controllerMap|コントローラマップ]] がカレント ID を含むかどうかを調べます。 もしそうであれば、マップの中で見つかったコントローラコンフィギュレーションに従ってコントローラオブジェクトが生成され、 ルートの残りの部分を処理するために、ステップ 5 に飛びます。 3. ID がカレントモジュールの [[yii\base\Module::modules|modules]] プロパティのリストに挙げられたモジュールを指すかどうかを調べます。 もしそうであれば、モジュールのリストで見つかったコンフィギュレーションに従ってモジュールが生成されます。そして、ステップ 2 に戻って、新しく生成されたモジュールのコンテキストのもとで、ルートの次の部分を処理します。 4. ID をコントローラ ID として扱ってコントローラオブジェクトを生成します。そしてルートの残りの部分を持って次のステップに進みます。 5. コントローラは、[[yii\base\Controller::actions()|アクションマップ]] の中にカレント ID があるかどうかを調べます。もし有れば、 マップの中で見つかったコンフィギュレーションに従ってアクションを生成します。もし無ければ、カレント ID に対応するアクションメソッドによって定義されるインラインアクションを生成しようと試みます。 上記のステップの中で、何かエラーが発生すると、[[yii\web\NotFoundHttpException]] が投げられて、 ルーティングのプロセスが失敗したことが示されます。 ### デフォルトルート リクエストから解析されたルートが空っぽになった場合は、いわゆる *デフォルトルート* が代りに使用されることになります。既定では、 デフォルトルートは `site/index` であり、`site` コントローラの `index` アクションを指します。デフォルトルートは、次のように、 アプリケーションコンフィギュレーションの中でアプリケーションの [[yii\web\Application::defaultRoute|defaultRoute]] プロパティを構成することによって、カスタマイズすることが出来ます。 ```php [ // ... 'defaultRoute' => 'main/index', ]; ``` ### `catchAll` ルート たまには、ウェブアプリケーションを一時的にメンテナンスモードにして、全てのリクエストに対して同じ「お知らせ」のページを表示したいことがあるでしょう。 この目的を達する方法はたくさんありますが、最も簡単な方法の一つは、次のように、 アプリケーションのコンフィギュレーションの中で [[yii\web\Application::catchAll]] プロパティを構成することです。 ```php [ // ... 'catchAll' => ['site/offline'], ]; ``` 上記のコンフィギュレーションによって、入ってくる全てのリクエストを処理するために `site/offline` アクションが使われるようになります。 `catchAll` プロパティは配列を取り、最初の要素はルートを指定し、残りの要素 (「名前-値」のペア) は [アクションのパラメータ](structure-controllers.md#action-parameters) を指定するものでなければなりません。 ## URL を生成する Yii は、与えられたルートとそれに結び付けられるクエリパラメータからさまざまな URL を生成する [[yii\helpers\Url::to()]] というヘルパーメソッドを提供しています。例えば、 ```php use yii\helpers\Url; // ルートへの URL を生成する: /index.php?r=post/index echo Url::to(['post/index']); // パラメータを持つルートへの URL を生成する: /index.php?r=post/view&id=100 echo Url::to(['post/view', 'id' => 100]); // アンカー付きの URL を生成する: /index.php?r=post/view&id=100#content echo Url::to(['post/view', 'id' => 100, '#' => 'content']); // 絶対 URL を生成する: http://www.example.com/index.php?r=post/index echo Url::to(['post/index'], true); // https スキームを使って絶対 URL を生成する: https://www.example.com/index.php?r=post/index echo Url::to(['post/index'], 'https'); ``` 上記の例では、既定の URL 形式が使われていると仮定していることに注意してください。綺麗な URL 形式が有効になっている場合は、生成される URL は、使われている [[yii\web\UrlManager::rules|URL 規則]] に従って、違うものになります。 [[yii\helpers\Url::to()]] メソッドに渡されるルートの意味は、コンテキストに依存します。ルートは *相対* ルートか *絶対* ルートかのどちらかであり、下記の規則によって正規化されます。 - ルートが空文字列である場合は、現在リクエストされている [[yii\web\Controller::route|ルート]] が使用されます。 - ルートがスラッシュを全く含まない場合は、カレントコントローラのアクション ID であると見なされて、 カレントコントローラの [[\yii\web\Controller::uniqueId|uniqueId]] の値が前置されます。 - ルートが先頭にスラッシュを含まない場合は、カレントモジュールに対する相対ルートと見なされて、 カレントモジュールの [[\yii\base\Module::uniqueId|uniqueId]] の値が前置されます。 例えば、カレントモジュールが `admin` であり、カレントコントローラが `post` であると仮定すると、 ```php use yii\helpers\Url; // 現在リクエストされているルート: /index.php?r=admin/post/index echo Url::to(['']); // アクション ID だけの相対ルート: /index.php?r=admin/post/index echo Url::to(['index']); // 相対ルート: /index.php?r=admin/post/index echo Url::to(['post/index']); // 絶対ルート: /index.php?r=post/index echo Url::to(['/post/index']); ``` [[yii\helpers\Url::to()]] メソッドは、[[yii\web\UrlManager|URL マネージャ]] の [[yii\web\UrlManager::createUrl()|createUrl()]] メソッド、および、[[yii\web\UrlManager::createAbsoluteUrl()|createAbsoluteUrl()]] を呼び出すことによって実装されています。 次に続くいくつかの項では、[[yii\web\UrlManager|URL マネージャ]] を構成して、生成される URL の形式をカスタマイズする方法を説明します。 [[yii\helpers\Url::to()]] メソッドは、特定のルートとの関係を持たない URL の生成もサポートしています。 その場合、最初のパラメータとして配列を渡す代りに文字列を渡さなければなりません。例えば、 ```php use yii\helpers\Url; // 現在リクエストされている URL: /index.php?r=admin/post/index echo Url::to(); // エイリアス化された URL: http://example.com Yii::setAlias('@example', 'http://example.com/'); echo Url::to('@example'); // 絶対 URL: http://example.com/images/logo.gif echo Url::to('/images/logo.gif', true); ``` `to()` メソッドの他にも、[[yii\helpers\Url]]` ヘルパークラスは、便利な URL 生成メソッドをいくつか提供しています。 例えば、 ```php use yii\helpers\Url; // ホームページの URL: /index.php?r=site/index echo Url::home(); // ベース URL。アプリケーションがウェブルートのサブディレクトリに配置されているときに便利 echo Url::base(); // 現在リクエストされている URL の canonical URL。 // https://en.wikipedia.org/wiki/Canonical_link_element を参照 echo Url::canonical(); // 現在リクエストされている URL を記憶し、それを後のリクエストの中で呼び戻す。 Url::remember(); echo Url::previous(); ``` ## 綺麗な URL を使う 綺麗な URL を使うためには、アプリケーションコンフィギュレーションの中で `urlManager` コンポーネントを次のように構成します。 ```php [ 'components' => [ 'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => false, 'enableStrictParsing' => true, 'rules' => [ // ... ], ], ], ] ``` [[yii\web\UrlManager::enablePrettyUrl|enablePrettyUrl]] プロパティは、綺麗な URL 形式の有効/無効を切り替えますので、必須です。 その他のプロパティはオプションですが、上記で示されているコンフィギュレーションが最もよく用いられているものです。 * [[yii\web\UrlManager::showScriptName|showScriptName]]: このプロパティは、エントリスクリプトを生成される URL に含めるべきかどうかを 決定します。例えば、このプロパティを true にすると、`/index.php/post/100` という URL を生成する代りに、`/post/100` という URL を生成することが出来ます。 * [[yii\web\UrlManager::enableStrictParsing|enableStrictParsing]]: このプロパティは、厳密なリクエスト解析を有効にするかどうかを決定します。 厳密な解析が有効にされた場合、リクエストされた URL が有効なリクエストとして扱われるためには、それが [[yii\web\UrlManager::rules|rules]] の少なくとも一つに合致しなければなりません。そうでなければ、[[yii\web\NotFoundHttpException]] が投げられます。 厳密な解析が無効にされると、リクエストされた URL が [[yii\web\UrlManager::rules|rules]] のどれにも合致しない場合は、 URL のパス情報の部分がリクエストされたルートとして扱われます。 * [[yii\web\UrlManager::rules|rules]]: このプロパティが URL を解析および生成するための一連の規則を含みます。 このプロパティが、アプリケーションの固有の要求を満たす形式を持つ URL を生成するために、あなたが主として使うプロパティです。 > Note|注意: 生成された URL からエントリスクリプト名を隠すためには、[[yii\web\UrlManager::showScriptName|showScriptName]] を true に設定するだけでなく、ウェブサーバを構成して、リクエストされた URL が PHP スクリプトを明示的に指定していない場合でも、 正しい PHP スクリプトを特定出来るようにする必要があります。もしあなたが Apache ウェブサーバを使うつもりなら、 [インストール](start-installation.md#recommended-apache-configuration) の節で説明されている推奨設定を参照することが出来ます。 ### URL 規則 URL 規則は [[yii\web\UrlRule]] またはその子クラスのインスタンスです。すべての URL 規則は、URL のパス情報の部分との照合に使われるパターン、 ルート、そして、いくつかのクエリパラメータから構成されます。URL 規則は、パターンがリクエストされた URL と合致する場合に、 リクエストの解析に使用することが出来ます。また、URL 規則は、ルートとクエリパラメータ名が与えられたものと合致する場合に、 URL の生成に使用することが出来ます。 綺麗な URL 形式が有効にされている場合、[[yii\web\UrlManager|URL マネージャ]] は、その [[yii\web\UrlManager::rules|rules]] プロパティに宣言されている URL 規則を使って、入ってくるリクエストを解析と URL の生成を行います。具体的に言えば、 入ってくるリクエストを解析するためには、[[yii\web\UrlManager|URL マネージャ]] は宣言されている順に規則を調べて、リクエストされた URL に合致する *最初の* 規則を探します。そして、その合致する規則を使って URL を解析して、ルートとそれと結合されたパラメータを得ます。 同じように、URL を生成するためには、[[yii\web\UrlManager|URL マネージャ]] は、与えられたルートとパラメータに合致する最初の規則を探して、 それを使って URL を生成します。 [[yii\web\UrlManager::rules]] は、パターンをキーとし、それに対応するルートを値とする配列として構成することが出来ます。 「パターン - ルート」のペアが、それぞれ、URL 規則を構成します。例えば、次の [[yii\web\UrlManager::rules|rules]] のコンフィギュレーションは、二つの URL 規則を宣言するものです。最初の規則は `posts` という URL に合致し、それを `post/index` というルートにマップします。第二の規則は `post/(\d+)` という正規表現にマッチする URL に合致し、それを `post/view` というルートと `id` という名前のパラメータにマップします。 ```php [ 'posts' => 'post/index', 'post/' => 'post/view', ] ``` > Info|情報: 規則のパターンは URL のパス情報の部分との照合に使用されます。例えば、`/index.php/post/100?source=ad` のパス情報は `post/100` であり (先頭と末尾のスラッシュは無視します)、これは `post/(\d+)` というパターンに合致します。 URL 規則は、「パターン - ルート」のペアとして宣言する以外に、コンフィギュレーション配列として宣言することも出来ます。 すべてのコンフィギュレーション配列が、それぞれ、一つの URL 規則のオブジェクトを構成するために使われます。この形式は、 URL 規則の他のプロパティを構成したい場合に、よく必要になります。例えば、 ```php [ // ... 他の URL 規則 ... [ 'pattern' => 'posts', 'route' => 'post/index', 'suffix' => '.json', ], ] ``` 規則のコンフィギュレーションで `class` を指定しない場合は、既定として、[[yii\web\UrlRule]] が使われます。 ### 名前付きパラメータ URL 規則は、パターンの中で `` の形式で指定される、いくつかの名前付きクエリパラメータと結び付けることが出来ます。 ここで、`ParamName` はパラメータ名を指定し、`RegExp` はパラメータの値との照合に使われるオプションの正規表現を指定するものです。 `RegExp` が指定されていない場合は、パラメータの値がスラッシュを含まない文字列であるべきことを意味します。 > Note|注意: 正規表現はパラメータに対してのみ指定できます。パターンの残りの部分は平文テキストであると見なされます。 規則が URL の解析に使われるときには、結び付けられたパラメータに、URL の対応する部分に合致する値が入れられます。 そして、これらのパラメータは、後に `request` アプリケーションコンポーネントによって、`$_GET` に入れられて利用できるようになります。 規則が URL の生成に使われるときは、提供されたパラメータの値を受けて、パラメータが宣言されている所にその値が挿入されます。 名前付きパラメータの動作を説明するためにいくつかの例を挙げましょう。次の三つの URL 規則を宣言したと仮定してください。 ```php [ 'posts' => 'post/index', 'post/' => 'post/view', 'posts//' => 'post/index', ] ``` 規則が URL 解析に使われる場合は: - `/index.php/posts` は、最初の規則を使って解析され、ルート `post/index` になります。 - `/index.php/posts/2014/php` は、三番目の規則を使って解析され、ルートは `post/index`、`year` パラメータの値は 2014、 そして、`category` パラメータの値は `php` となります。 - `/index.php/post/100` は、二番目の規則を使って解析され、ルートが `post/view`、`id` パラメータの値が 100 となります。 - `/index.php/posts/php` は、どのパターンにも合致しないため、[[yii\web\UrlManager::enableStrictParsing]] が true の場合は、 [[yii\web\NotFoundHttpException]] を引き起こします。[[yii\web\UrlManager::enableStrictParsing]] が false (これが既定値です) の場合は、パス情報の部分である `posts/php` がルートとして返されることになります。 規則が URL 生成に使われる場合は: - `Url::to(['post/index'])` は、最初の規則を使って、`/index.php/posts` を生成します。 - `Url::to(['post/index', 'year' => 2014, 'category' => 'php'])` は、三番目の規則を使って、`/index.php/posts/2014/php` を生成します。 - `Url::to(['post/view', 'id' => 100])` は、二番目の規則を使って、`/index.php/post/100` を生成します。 - `Url::to(['post/view', 'id' => 100, 'source' => 'ad'])` も、二番目の規則を使って、`/index.php/post/100?source=ad` を生成します。 `source` パラメータは規則の中で指定されていないので、クエリパラメータとして生成された URL に追加されます。 - `Url::to(['post/index', 'category' => 'php'])` は、どの規則も使わずに、`/index.php/post/index?category=php` を生成します。 どの規則も当てはまらないため、URL は、単純に、ルートをパス情報とし、すべてのパラメータをクエリ文字列として追加して生成されます。 ### ルートをパラメータ化する URL 規則のルートにはパラメータ名を埋め込むことが出来ます。このことによって、URL 規則を複数のルートに合致させることが可能になっています。 例えば、以下の規則は `controller` と `action` というパラメータをルートに埋め込んでいます。 ```php [ '//' => '/', '/' => '/view', 's' => '/index', ] ``` `/index.php/comment/100/create` という URL の解析には、最初の規則が適用され、`controller` パラメータには `comment`、 `action` パラメータには `create` がセットされます。こうして、`/` というルートは、`comment/create` として解決されます。 同じように、`comment/index` というルートの URL を生成するためには、三番目の規則が適用されて、`index.php/comments` という URL が生成されます。 > Info|情報: ルートをパラメータ化することによって、URL 規則の数を大幅に減らすことが可能になり、 [[yii\web\UrlManager|URL マネージャ]] のパフォーマンスを目に見えて改善することが出来ます。 既定では、規則の中で宣言されたパラメータは必須となります。リクエストされた URL が特定のパラメータを含まない場合や、 URL が特定のパラメータなしで生成される場合には、規則は適用されません。パラメータのどれかをオプション扱いにしたい場合は、規則の [[yii\web\UrlRule::defaults|defaults]] プロパティを構成することが出来ます。このプロパティのリストに挙げられたパラメータは オプション扱いとなり、規定されなかった場合は指定された値を取るようになります。 次の規則の宣言においては、`page` と `tag` のパラメータは両方ともオプション扱いで、規定されなかった場合は、それぞれ、1 と空文字列を取ります。 ```php [ // ... 他の規則 ... [ 'pattern' => 'posts//', 'route' => 'post/index', 'defaults' => ['page' => 1, 'tag' => ''], ], ] ``` 上記の規則を以下の URL を解析または生成するために使用することが出来ます。 * `/index.php/posts`: `page` は 1, `tag` は ''. * `/index.php/posts/2`: `page` は 2, `tag` は ''. * `/index.php/posts/2/news`: `page` は 2, `tag` は `'news'`. * `/index.php/posts/news`: `page` は 1, `tag` は `'news'`. オプション扱いのパラメータを使わなければ、同じ結果を得るために 4 個の規則を作らなければならなかったところです。 ### サーバ名を持つ規則 URL 規則のパターンには、ウェブサーバ名を含むことが出来ます。このことが役に立つのは、主として、あなたのアプリケーションが ウェブサーバ名によって異なる動作をしなければならない場合です。例えば、次の規則は、`http://admin.example.com/login` という URL を `admin/user/login` のルートとして解析し、`http://www.example.com/login` を `site/login` として解析するものです。 ```php [ 'http://admin.example.com/login' => 'admin/user/login', 'http://www.example.com/login' => 'site/login', ] ``` サーバ名にパラメータを埋め込んで、そこから動的な情報を抽出することも出来ます。例えば、次の規則は `http://en.example.com/posts` という URL を解析して、`post/index` というルートと `language=en` というパラメータを取得するものです。 ```php [ 'http://.example.com/posts' => 'post/index', ] ``` > Note|注意: サーバ名を持つ規則は、エントリスクリプトのサブフォルダをパターンに含むべきではありません。例えば、アプリケーションが `http://www.example.com/sandbox/blog` の下にある場合は、`http://www.example.com/sandbox/blog/posts` ではなく、 `http://www.example.com/posts` というパターンを使うべきです。こうすれば、アプリケーションをどのようなディレクトリに配置しても、 アプリケーションのコードを変更する必要がなくなります。 ### URL 接尾辞 さまざまな目的から URL に接尾辞を追加したいことがあるでしょう。例えば、静的な HTML ページに見えるように、`.html` を URL に追加したいかも知れません。また、レスポンスとして期待されているコンテントタイプを示すために、`.json` を URL に追加したい場合もあるでしょう。アプリケーションのコンフィギュレーションで、次のように、[[yii\web\UrlManager::suffix]] プロパティを構成することによって、この目的を達することが出来ます。 ```php [ 'components' => [ 'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => false, 'enableStrictParsing' => true, 'suffix' => '.html', 'rules' => [ // ... ], ], ], ] ``` 上記のコンフィギュレーションによって、[[yii\web\UrlManager|URL マネージャ]] は、接尾辞として `.html` の付いた URL を認識し、また、生成するようになります。 > Tip|ヒント: URL が全てスラッシュで終るようにするためには、URL 接尾辞として `/` を設定することが出来ます。 > Note|注意: URL 接尾辞を構成すると、リクエストされた URL が接尾辞を持たない場合は、認識できない URL であると見なされるようになります。 SEO の目的からも、これが推奨される慣行です。 場合によっては、URL によって異なる接尾辞を使いたいことがあるでしょう。その目的は、個々の URL 規則の [[yii\web\UrlRule::suffix|suffix]] プロパティを構成することによって達成できます。URL 規則にこのプロパティが設定されている場合は、それが [[yii\web\UrlManager|URL マネージャ]] レベルの接尾辞の設定をオーバーライドします。例えば、次のコンフィギュレーションには、グローバルな接尾辞 `.html` の代りに `.json` を使用するカスタマイズされた URL 規則が含まれています。 ```php [ 'components' => [ 'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => false, 'enableStrictParsing' => true, 'suffix' => '.html', 'rules' => [ // ... [ 'pattern' => 'posts', 'route' => 'post/index', 'suffix' => '.json', ], ], ], ], ] ``` ### HTTP メソッド RESTful API を実装するときは、使用されている HTTP メソッドに応じて、同一の URL を異なるルートとして解析することが 必要になル場合がよくあります。これは、規則のパターンにサポートされている HTTP メソッドを前置することによって、 簡単に達成することが出来ます。一つの規則が複数の HTTP メソッドをサポートする場合は、メソッド名をカンマで区切ります。 例えば、次の三つの規則は、`post/` という同一のパターンを持って、異なる HTTP メソッドをサポートするものです。 `PUT post/100` に対するリクエストは `post/create` と解析され、`GET post/100` に対するリクエストは `post/view` と解析されることになります。 ```php [ 'PUT,POST post/' => 'post/create', 'DELETE post/' => 'post/delete', 'post/' => 'post/view', ] ``` > Note|注意: URL 規則が HTTP メソッドをパターンに含む場合、その規則は解析目的にだけ使用されます。[[yii\web\UrlManager|URL マネージャ]] が URL 生成のために呼ばれたときは、その規則はスキップされます。 > Tip|ヒント: RESTful API のルーティングを簡単にするために、Yii は特別な URL 規則クラス [[yii\rest\UrlRule]] を提供しています。 これは非常に効率的なもので、コントローラ ID の自動的な複数形化など、いくつかの素敵な機能をサポートするものです。 詳細については、RESTful API 開発についての [ルーティング](rest-routing.md) の節を参照してください。 ### 規則をカスタマイズする これまでの例では、URL 規則は主として「パターン - ルート」のペアの形で宣言されています。これが通常使用される短縮形式です。 特定のシナリオの下では、[[yii\web\UrlRule::suffix]] などのような、他のプロパティを構成して URL 規則をカスタマイズしたいことも あるでしょう。完全なコンフィギュレーション配列を使って規則を指定すれば、そうすることが出来ます。次の例は、[URL 接尾辞](#url-suffixes) の項から抜き出したものです。 ```php [ // ... 他の URL 規則 ... [ 'pattern' => 'posts', 'route' => 'post/index', 'suffix' => '.json', ], ] ``` > Info|情報: 規則のコンフィギュレーションで `class` を指定しない場合は、既定として、[[yii\web\UrlRule]] クラスが使われます。 ### 規則を動的に追加する URL 規則は [[yii\web\UrlManager|URL マネージャ]] に動的に追加することが出来ます。このことは、再配布可能な [モジュール](structure-modules.md) が自分自身の URL 規則を管理する必要がある場合に、しばしば必要になります。動的に追加された規則がルーティングのプロセスで効果を発揮するためには、 その規則を [ブートストラップ](runtime-bootstrapping.md) の段階で追加しなければなりません。これは、モジュールにとっては、次のように、 [[yii\base\BootstrapInterface]] を実装して、[[yii\base\BootstrapInterface::bootstrap()|bootstrap()]] メソッドの中で規則を追加しなければならないことを意味します。 ```php public function bootstrap($app) { $app->getUrlManager()->addRules([ // ここに規則の宣言 ], false); } ``` さらに、モジュールが [ブートストラップ](runtime-bootstrapping.md) の過程に関与できるように、それを [[yii\web\Application::bootstrap]] のリストに挙げなければならないことに注意してください。 ### 規則クラスを作成する デフォルトの [[yii\web\UrlRule]] クラスはほとんどのプロジェクトに対して十分に柔軟なものであるというのは事実ですが、 それでも、自分自身で規則クラスを作る必要があるような状況はあります。例えば、自動車ディーラーのウェブサイトにおいて、 `/Manufacturer/Model` のような URL 形式をサポートしたいけれども、`Manufacturer` と `Model` は、両方とも、 データベーステーブルに保存されている何らかのデータに合致するものでなければならない、というような場合です。 デフォルトの規則クラスは、静的に宣言されるパターンに依拠しているため、ここでは役に立ちません。 この問題を解決するために、次のような URL 規則クラスを作成することが出来ます。 ```php namespace app\components; use yii\web\UrlRuleInterface; use yii\base\Object; class CarUrlRule extends Object implements UrlRuleInterface { public function createUrl($manager, $route, $params) { if ($route === 'car/index') { if (isset($params['manufacturer'], $params['model'])) { return $params['manufacturer'] . '/' . $params['model']; } elseif (isset($params['manufacturer'])) { return $params['manufacturer']; } } return false; // この規則は適用されない } public function parseRequest($manager, $request) { $pathInfo = $request->getPathInfo(); if (preg_match('%^(\w+)(/(\w+))?$%', $pathInfo, $matches)) { // $matches[1] と $matches[3] をチェックして、 // データベースの中の製造者とモデルに合致するかどうか調べる // 合致すれば、$params['manufacturer'] および/または $params['model'] をセットし、 // ['car/index', $params] を返す } return false; // この規則は適用されない } } ``` そして、[[yii\web\UrlManager::rules]] のコンフィギュレーションで、新しい規則クラスを使います。 ```php [ // ... 他の規則 ... [ 'class' => 'app\components\CarUrlRule', // ... 他のプロパティを構成する ... ], ] ``` ## パフォーマンスに対する考慮 複雑なウェブアプリケーションを開発するときは、リクエストの解析と URL 生成に要する時間を削減するために URL 規則を最適化することが重要になります。 パラメータ化したルートを使うことによって、URL 規則の数を減らして、パフォーマンスを著しく向上させることが出来ます。 URL を解析または生成するときに、[[yii\web\UrlManager|URL マネージャ]] は、宣言された順序で URL 規則を調べます。 従って、より多く使われる規則がより少なく使われる規則より前に来るように順序を調整することを検討してください。 パターンまたはルートに共通の先頭部分を持つ URL 規則がある場合は、[[yii\web\UrlManager|URL マネージャ]] がそれらをグループ化して効率的に調べることが出来るように、[[yii\web\GroupUrlRule]] を使うことを検討してください。 あなたのアプリケーションがモジュールによって構成されており、モジュールごとに、モジュール ID を共通の先頭部分とする 一群の URL 規則を持っている場合は、通常、このことが当てはまります。