8 フォロワー

ルーティングとURL生成

Yii アプリケーションがリクエストされた URL の処理を開始すると、最初に行うステップは URL を ルートに解析することです。次に、そのルートを使用して、リクエストを処理する対応するコントローラアクションをインスタンス化します。このプロセス全体をルーティングと呼びます。

ルーティングの逆のプロセスをURL生成と呼びます。これは、指定されたルートと関連するクエリパラメータから URL を生成します。生成された URL が後でリクエストされると、ルーティングプロセスによって元のルートとクエリパラメータに解析し直されます。

ルーティングとURL生成を担当する中心的な要素は、urlManager アプリケーションコンポーネントとして登録されているURLマネージャです。URLマネージャは、受信リクエストをルートと関連するクエリパラメータに解析するparseRequest()メソッドと、指定されたルートとその関連するクエリパラメータからURLを作成するcreateUrl()メソッドを提供します。

アプリケーション構成でurlManagerコンポーネントを構成することにより、既存のアプリケーションコードを変更せずに、アプリケーションが任意のURL形式を認識できるようにすることができます。たとえば、次のコードを使用して、post/viewアクションのURLを作成できます。

use yii\helpers\Url;

// Url::to() calls UrlManager::createUrl() to create a URL
$url = Url::to(['post/view', 'id' => 100]);

urlManager構成に応じて、作成されたURLは次のいずれかの形式になる場合があります(またはその他の形式)。作成されたURLが後でリクエストされた場合でも、元のルートとクエリパラメータ値に解析し直されます。

/index.php?r=post%2Fview&id=100
/index.php/post/100
/posts/100

URL形式

URLマネージャは、次の2つのURL形式をサポートしています。

  • デフォルトのURL形式;
  • きれいなURL形式。

デフォルトのURL形式では、クエリパラメータ r を使用してルートを表し、通常のクエリパラメータを使用してルートに関連付けられたクエリパラメータを表します。たとえば、URL /index.php?r=post/view&id=100 は、ルート post/viewid クエリパラメータ 100 を表します。デフォルトのURL形式では、URLマネージャの構成は必要なく、あらゆるWebサーバー構成で動作します。

きれいなURL形式は、エントリスクリプト名の後の追加のパスを使用して、ルートと関連するクエリパラメータを表します。たとえば、URL /index.php/post/100 の追加のパスは /post/100 であり、これは適切な URL規則 を使用して、ルート post/viewid クエリパラメータ 100 を表す場合があります。きれいなURL形式を使用するには、URLがどのように表示されるべきかに関する実際の要件に従って、URL規則 のセットを設計する必要があります。

URLマネージャenablePrettyUrl プロパティを切り替えることで、他のアプリケーションコードを変更することなく、2つのURL形式を切り替えることができます。

ルーティング

ルーティングには2つのステップが含まれます。

  • 受信リクエストがルートと関連するクエリパラメータに解析される。
  • 解析されたルートに対応する コントローラアクション が作成され、リクエストを処理します。

デフォルトのURL形式を使用する場合、リクエストをルートに解析するのは、r という名前の GET クエリパラメータの値を取得するのと同じくらい簡単です。

きれいなURL形式を使用する場合、URLマネージャ は、登録された URL規則 を調べて、リクエストをルートに解決できる一致するものを探します。そのような規則が見つからない場合、yii\web\NotFoundHttpException 例外がスローされます。

リクエストがルートに解析されると、ルートによって識別されるコントローラアクションを作成する時間になります。ルートは、その中のスラッシュによって複数の部分に分割されます。たとえば、site/indexsiteindex に分割されます。各部分は、モジュール、コントローラ、またはアクションを参照する可能性のあるIDです。ルートの最初の部分から開始して、アプリケーションは次の手順を実行して、モジュール(存在する場合)、コントローラ、およびアクションを作成します。

  1. アプリケーションを現在のモジュールとして設定します。
  2. 現在のモジュールの コントローラマップ に現在のIDが含まれているかどうかを確認します。含まれている場合は、マップで見つかったコントローラ構成に従ってコントローラオブジェクトが作成され、残りのルートを処理するためにステップ5が実行されます。
  3. IDが、現在のモジュールの モジュール プロパティにリストされているモジュールを参照しているかどうかを確認します。その場合は、モジュールリストで見つかった構成に従ってモジュールが作成され、新しく作成されたモジュールのコンテキストで次のルート部分を処理するためにステップ2が実行されます。
  4. IDを コントローラID として扱い、コントローラオブジェクトを作成します。残りのルートで次のステップを実行します。
  5. コントローラは、アクションマップ で現在のIDを探します。見つかった場合は、マップで見つかった構成に従ってアクションを作成します。それ以外の場合、コントローラは、現在の アクションID に対応するアクションメソッドによって定義されたインラインアクションを作成しようとします。

上記の手順のうち、エラーが発生した場合、yii\web\NotFoundHttpException がスローされ、ルーティングプロセスの失敗が示されます。

デフォルトルート

リクエストが空のルートに解析されると、代わりに、いわゆるデフォルトルートが使用されます。デフォルトでは、デフォルトルートは site/index であり、site コントローラの index アクションを参照します。アプリケーション構成で、次の例のようにアプリケーションの defaultRoute プロパティを構成することで、これをカスタマイズできます。

[
    // ...
    'defaultRoute' => 'main/index',
];

アプリケーションのデフォルトルートと同様に、モジュールにもデフォルトルートがあります。たとえば、user モジュールがあり、リクエストがルート user に解析された場合、モジュールの defaultRoute がコントローラを決定するために使用されます。デフォルトでは、コントローラ名は default です。defaultRoute にアクションが指定されていない場合、コントローラの defaultAction プロパティがアクションを決定するために使用されます。この例では、完全なルートは user/default/index になります。

catchAll ルート

場合によっては、Webアプリケーションを一時的にメンテナンスモードにして、すべてのリクエストに対して同じ情報ページを表示したい場合があります。この目標を達成する方法はたくさんあります。ただし、最も簡単な方法の1つは、アプリケーション構成で次のように yii\web\Application::$catchAll プロパティを構成することです。

[
    // ...
    'catchAll' => ['site/offline'],
];

上記の構成では、site/offline アクションがすべての受信リクエストを処理するために使用されます。

catchAll プロパティは、最初の要素がルートを指定し、残りの要素(名前と値のペア)が アクションにバインドされる パラメータを指定する配列を受け取る必要があります。

情報: このプロパティが有効になっている場合、開発環境の デバッグツールバー は機能しません。

URLの作成

Yiiは、与えられたルートとそれに関連するクエリパラメータからさまざまな種類のURLを作成するためのヘルパーメソッド yii\helpers\Url::to() を提供します。例:

use yii\helpers\Url;

// creates a URL to a route: /index.php?r=post%2Findex
echo Url::to(['post/index']);

// creates a URL to a route with parameters: /index.php?r=post%2Fview&id=100
echo Url::to(['post/view', 'id' => 100]);

// creates an anchored URL: /index.php?r=post%2Fview&id=100#content
echo Url::to(['post/view', 'id' => 100, '#' => 'content']);

// creates an absolute URL: https://www.example.com/index.php?r=post%2Findex
echo Url::to(['post/index'], true);

// creates an absolute URL using the https scheme: https://www.example.com/index.php?r=post%2Findex
echo Url::to(['post/index'], 'https');

上記の例では、デフォルトのURL形式が使用されていると仮定します。きれいなURL形式が有効になっている場合、使用中の URL規則 に応じて、作成されたURLは異なります。

yii\helpers\Url::to() メソッドに渡されるルートは、コンテキストに依存します。これは、相対 ルートまたは 絶対 ルートのいずれかであり、次の規則に従って正規化されます。

  • ルートが空の文字列の場合、現在リクエストされている ルート が使用されます。
  • ルートにスラッシュがまったく含まれていない場合は、現在のコントローラのアクションIDと見なされ、現在のコントローラの uniqueId 値が前に付加されます。
  • ルートの先頭にスラッシュがない場合、現在のモジュールに対する相対ルートと見なされ、現在のモジュールの uniqueId 値が前に付加されます。

バージョン2.0.2以降では、エイリアス の形式でルートを指定できます。この場合、エイリアスは最初に実際のルートに変換され、次に上記の規則に従って絶対ルートに変換されます。

たとえば、現在のモジュールが admin で、現在のコントローラが post であると仮定します。

use yii\helpers\Url;

// currently requested route: /index.php?r=admin%2Fpost%2Findex
echo Url::to(['']);

// a relative route with action ID only: /index.php?r=admin%2Fpost%2Findex
echo Url::to(['index']);

// a relative route: /index.php?r=admin%2Fpost%2Findex
echo Url::to(['post/index']);

// an absolute route: /index.php?r=post%2Findex
echo Url::to(['/post/index']);

// using an alias "@posts", which is defined as "/post/index": /index.php?r=post%2Findex
echo Url::to(['@posts']);

yii\helpers\Url::to() メソッドは、URLマネージャcreateUrl() メソッドと createAbsoluteUrl() メソッドを呼び出すことによって実装されます。次のいくつかのサブセクションでは、作成されたURLの形式をカスタマイズするために URLマネージャ を構成する方法について説明します。

yii\helpers\Url::to() メソッドは、特定のルートに関連付けられていないURLの作成もサポートしています。最初のパラメータとして配列を渡す代わりに、この場合は文字列を渡す必要があります。例:

use yii\helpers\Url;

// currently requested URL: /index.php?r=admin%2Fpost%2Findex
echo Url::to();

// an aliased URL: https://example.com
Yii::setAlias('@example', 'https://example.com/');
echo Url::to('@example');

// an absolute URL: https://example.com/images/logo.gif
echo Url::to('/images/logo.gif', true);

to() メソッドに加えて、yii\helpers\Url ヘルパークラスは、他にもいくつかの便利なURL作成メソッドを提供します。例:

use yii\helpers\Url;

// home page URL: /index.php?r=site%2Findex
echo Url::home();

// the base URL, useful if the application is deployed in a sub-folder of the Web root
echo Url::base();

// the canonical URL of the currently requested URL
// see https://en.wikipedia.org/wiki/Canonical_link_element
echo Url::canonical();

// remember the currently requested URL and retrieve it back in later requests
Url::remember();
echo Url::previous();

きれいなURLの使用

きれいなURLを使用するには、アプリケーション構成で次のように urlManager コンポーネントを構成します。

[
    'components' => [
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'enableStrictParsing' => false,
            'rules' => [
                // ...
            ],
        ],
    ],
]

enablePrettyUrl プロパティは、きれいなURL形式を切り替えるため必須です。残りのプロパティはオプションです。ただし、上記に示されている構成は最も一般的に使用されます。

  • showScriptName: このプロパティは、作成されたURLにエントリスクリプトを含める必要があるかどうかを決定します。たとえば、URL /index.php/post/100 を作成する代わりに、このプロパティを false に設定すると、URL /post/100 が生成されます。
  • enableStrictParsing: このプロパティは、厳密なリクエスト解析を有効にするかどうかを決定します。厳密な解析が有効になっている場合、受信したリクエストURLは、有効なリクエストとして扱われるために、少なくとも1つの 規則 と一致する必要があります。それ以外の場合、yii\web\NotFoundHttpException がスローされます。厳密な解析が無効になっている場合、規則 のいずれも要求されたURLと一致しない場合、URLのパス情報部分が要求されたルートとして扱われます。
  • rules: このプロパティには、URLの解析と作成方法を指定する規則のリストが含まれています。これは、特定のアプリケーション要件を満たす形式のURLを作成するために作業する必要がある主要なプロパティです。

注: 作成されたURLでエントリスクリプト名を非表示にするには、showScriptNamefalse に設定することに加えて、要求されたURLでPHPスクリプトが明示的に指定されていない場合に、どのPHPスクリプトを実行する必要があるかをWebサーバーが正しく識別できるように構成する必要がある場合があります。Apacheまたはnginx Webサーバーを使用している場合は、インストール セクションで説明されている推奨構成を参照してください。

URL規則

URL規則は、yii\web\UrlRuleInterface (通常は yii\web\UrlRule)を実装するクラスです。各URL規則は、URLのパス情報部分を一致させるために使用されるパターン、ルート、およびいくつかのクエリパラメータで構成されます。URL規則のパターンが要求されたURLと一致する場合、URL規則を使用してリクエストを解析できます。URL規則のルートとクエリパラメータ名が指定されたものと一致する場合、URL規則を使用してURLを作成できます。

きれいな URL 形式が有効になっている場合、URL マネージャは、その rules プロパティで宣言された URL ルールを使って、受信リクエストを解析し、URL を作成します。特に、受信リクエストを解析するために、URL マネージャは、宣言された順序でルールを調べ、リクエストされた URL に一致する最初のルールを探します。一致するルールは、URL をルートとそれに関連するパラメータに解析するために使用されます。同様に、URL を作成するために、URL マネージャは、指定されたルートとパラメータに一致する最初のルールを探し、それを使って URL を作成します。

yii\web\UrlManager::$rules は、キーが パターン で、値が対応する ルート である配列として構成できます。各パターングルートのペアは、URL ルールを構成します。たとえば、次の rules 設定は、2 つの URL ルールを宣言しています。最初のルールは、URL posts に一致し、それをルート post/index にマップします。2 番目のルールは、正規表現 post/(\d+) に一致する URL に一致し、それをルート post/view にマップし、id という名前のクエリパラメータを定義します。

'rules' => [
    'posts' => 'post/index',
    'post/<id:\d+>' => 'post/view',
]

情報: ルール内のパターンは、URL のパス情報部分を一致させるために使用されます。たとえば、/index.php/post/100?source=ad のパス情報は post/100 です (先頭と末尾のスラッシュは無視されます)。これはパターン post/(\d+) に一致します。

URL ルールをパターングルートペアとして宣言するだけでなく、設定配列として宣言することもできます。各設定配列は、単一の URL ルールオブジェクトを構成するために使用されます。これは、URL ルールの他のプロパティを構成する場合によく必要になります。たとえば、

'rules' => [
    // ...other url rules...
    [
        'pattern' => 'posts',
        'route' => 'post/index',
        'suffix' => '.json',
    ],
]

デフォルトでは、ルール設定に class オプションを指定しない場合、デフォルトのクラス yii\web\UrlRule が適用されます。これは、yii\web\UrlManager::$ruleConfig で定義されたデフォルト値です。

名前付きパラメータ

URL ルールは、<ParamName:RegExp> の形式でパターンに指定された名前付きクエリパラメータに関連付けることができます。ここで、ParamName はパラメータ名を指定し、RegExp はパラメータ値を一致させるために使用されるオプションの正規表現です。RegExp が指定されていない場合、パラメータ値はスラッシュを含まない文字列である必要があることを意味します。

注: パラメータ内でのみ正規表現を使用できます。パターンの残りの部分はプレーンテキストと見なされます。

ルールが URL を解析するために使用される場合、関連するパラメータには URL の対応する部分に一致する値が入力され、これらのパラメータは後で request アプリケーションコンポーネントによって $_GET で利用可能になります。ルールが URL を作成するために使用される場合、提供されたパラメータの値を取得し、パラメータが宣言されている場所に挿入します。

いくつかの例を使って、名前付きパラメータがどのように機能するかを説明しましょう。次の 3 つの URL ルールを宣言したと仮定します。

'rules' => [
    'posts/<year:\d{4}>/<category>' => 'post/index',
    'posts' => 'post/index',
    'post/<id:\d+>' => 'post/view',
]

ルールが URL を解析するために使用される場合

  • /index.php/posts は、2 番目のルールを使用してルート post/index に解析されます。
  • /index.php/posts/2014/php は、最初のルールを使用して、ルート post/index、値が 2014 の year パラメータ、および値が phpcategory パラメータに解析されます。
  • /index.php/post/100 は、3 番目のルールを使用して、ルート post/view と値が 100 の id パラメータに解析されます。
  • yii\web\UrlManager::$enableStrictParsingtrue の場合、/index.php/posts/php は、どのパターンにも一致しないため、yii\web\NotFoundHttpException を発生させます。yii\web\UrlManager::$enableStrictParsingfalse (デフォルト値) の場合、パス情報部分 posts/php がルートとして返されます。これにより、対応するアクションが存在する場合は実行され、それ以外の場合は yii\web\NotFoundHttpException がスローされます。

そして、ルールが URL を作成するために使用される場合

  • Url::to(['post/index']) は、2 番目のルールを使用して /index.php/posts を作成します。
  • Url::to(['post/index', 'year' => 2014, 'category' => 'php']) は、最初のルールを使用して /index.php/posts/2014/php を作成します。
  • Url::to(['post/view', 'id' => 100]) は、3 番目のルールを使用して /index.php/post/100 を作成します。
  • Url::to(['post/view', 'id' => 100, 'source' => 'ad']) は、3 番目のルールを使用して /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 パラメータを埋め込みます。

'rules' => [
    '<controller:(post|comment)>/create' => '<controller>/create',
    '<controller:(post|comment)>/<id:\d+>/<action:(update|delete)>' => '<controller>/<action>',
    '<controller:(post|comment)>/<id:\d+>' => '<controller>/view',
    '<controller:(post|comment)>s' => '<controller>/index',
]

URL /index.php/comment/100/update を解析するには、2 番目のルールが適用され、controller パラメータが comment に、action パラメータが update に設定されます。したがって、ルート <controller>/<action>comment/update として解決されます。

同様に、ルート comment/index の URL を作成するには、最後のルールが適用され、URL /index.php/comments が作成されます。

情報: ルートをパラメータ化することにより、URL ルールの数を大幅に減らすことができ、URL マネージャのパフォーマンスを大幅に向上させることができます。

デフォルトパラメータ値

デフォルトでは、ルールで宣言されたすべてのパラメータは必須です。リクエストされた URL に特定のパラメータが含まれていない場合、または特定のパラメータなしで URL が作成されている場合、ルールは適用されません。一部のパラメータをオプションにするには、ルールの defaults プロパティを構成できます。このプロパティにリストされているパラメータはオプションであり、提供されていない場合は指定された値が使用されます。

次のルール宣言では、page パラメータと tag パラメータはどちらもオプションであり、提供されていない場合は、それぞれ値 1 と空文字列が使用されます。

'rules' => [
    // ...other rules...
    [
        'pattern' => 'posts/<page:\d+>/<tag>',
        '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 つのルールを作成する必要があります。

注: pattern にオプションのパラメータとスラッシュのみが含まれている場合、最初のパラメータは他のすべてのパラメータが省略されている場合にのみ省略できます。

サーバー名を持つルール

URL ルールのパターンに Web サーバー名を含めることができます。これは主に、アプリケーションが異なる Web サーバー名に対して異なる動作をする必要がある場合に役立ちます。たとえば、次のルールは、URL https://admin.example.com/login をルート admin/user/login に解析し、https://www.example.com/loginsite/login に解析します。

'rules' => [
    'https://admin.example.com/login' => 'admin/user/login',
    'https://www.example.com/login' => 'site/login',
]

サーバー名にパラメータを埋め込んで、そこから動的な情報を抽出することもできます。たとえば、次のルールは、URL https://en.example.com/posts をルート post/index およびパラメータ language=en に解析します。

'rules' => [
    'https://<language:\w+>.example.com/posts' => 'post/index',
]

バージョン 2.0.11 以降では、httphttps の両方で動作するプロトコル相対パターンを使用することもできます。構文は上記と同じですが、http: 部分をスキップします。例: '//www.example.com/login' => 'site/login'

注: サーバー名を持つルールは、パターンにエントリスクリプトのサブフォルダを含めないでください。たとえば、アプリケーションのエントリスクリプトが https://www.example.com/sandbox/blog/index.php にある場合、https://www.example.com/sandbox/blog/posts ではなく、パターン https://www.example.com/posts を使用する必要があります。これにより、URL ルールを変更する必要なしに、アプリケーションを任意のディレクトリにデプロイできます。Yii は、アプリケーションのベース URL を自動的に検出します。

URL サフィックス

さまざまな目的で URL にサフィックスを追加したい場合があります。たとえば、URL が静的 HTML ページの URL のように見えるように、URL に .html を追加したり、応答の予期されるコンテンツタイプを示すために URL に .json を追加したりできます。アプリケーション設定で、次のように yii\web\UrlManager::$suffix プロパティを構成することで、この目標を達成できます。

[
    // ...
    'components' => [
        'urlManager' => [
            'enablePrettyUrl' => true,
            // ...
            'suffix' => '.html',
            'rules' => [
                // ...
            ],
        ],
    ],
]

上記の設定により、URL マネージャは、リクエストされた URL を認識し、.html をサフィックスとして使用して URL を作成できるようになります。

ヒント: URL がすべてスラッシュで終わるように、URL サフィックスとして / を設定できます。

注: URL サフィックスを設定すると、リクエストされた URL にサフィックスがない場合、認識されない URL と見なされます。これは、異なる URL での重複コンテンツを回避するための SEO (検索エンジン最適化) に推奨される方法です。

場合によっては、異なる URL に異なるサフィックスを使用したい場合があります。これは、個々の URL ルールの suffix プロパティを構成することで実現できます。URL ルールにこのプロパティが設定されている場合、URL マネージャレベルでのサフィックス設定が上書きされます。たとえば、次の構成には、グローバルな .html サフィックスの代わりに .json をサフィックスとして使用するカスタマイズされた URL ルールが含まれています。

[
    'components' => [
        'urlManager' => [
            'enablePrettyUrl' => true,
            // ...
            'suffix' => '.html',
            'rules' => [
                // ...
                [
                    'pattern' => 'posts',
                    'route' => 'post/index',
                    'suffix' => '.json',
                ],
            ],
        ],
    ],
]

HTTPメソッド

RESTful APIを実装する際、同じURLが使用されるHTTPメソッドに応じて異なるルートに解析されることがよくあります。これは、ルールパターンにサポートされているHTTPメソッドをプレフィックスとして付けることで簡単に実現できます。ルールが複数のHTTPメソッドをサポートしている場合は、メソッド名をカンマで区切ります。たとえば、次のルールは、異なるHTTPメソッドのサポートを持つ同じパターンpost/<id:\d+>を持っています。PUT post/100のリクエストはpost/updateに解析され、GET post/100のリクエストはpost/viewに解析されます。

'rules' => [
    'PUT,POST post/<id:\d+>' => 'post/update',
    'DELETE post/<id:\d+>' => 'post/delete',
    'post/<id:\d+>' => 'post/view',
]

注意: URLルールにパターン内でHTTPメソッドが含まれている場合、そのルールはGETが指定された動詞に含まれない限り、解析の目的でのみ使用されます。URLを生成するためにURLマネージャが呼び出された場合はスキップされます。

ヒント: RESTful APIのルーティングを簡略化するために、Yiiは特別なURLルールクラスyii\rest\UrlRuleを提供します。これは非常に効率的で、コントローラIDの自動複数化などの高度な機能をサポートしています。詳細については、RESTful APIの章のルーティングセクションを参照してください。

動的なルール追加

URLルールは、URLマネージャに動的に追加できます。これは、独自のURLルールを管理したい再配布可能なモジュールでしばしば必要となります。動的に追加されたルールがルーティングプロセス中に有効になるようにするには、アプリケーションのブートストラップ段階で追加する必要があります。モジュールの場合、これはyii\base\BootstrapInterfaceを実装し、次のようにbootstrap()メソッドでルールを追加する必要があることを意味します。

public function bootstrap($app)
{
    $app->getUrlManager()->addRules([
        // rule declarations here
    ], false);
}

これらのモジュールは、yii\web\Application::bootstrap()にもリストして、ブートストラッププロセスに参加できるようにする必要があることに注意してください。

ルールクラスの作成

デフォルトのyii\web\UrlRuleクラスはほとんどのプロジェクトに十分な柔軟性がありますが、独自のルールクラスを作成する必要がある状況もあります。たとえば、自動車ディーラーのWebサイトでは、/Manufacturer/ModelのようなURL形式をサポートしたい場合があります。ここで、ManufacturerModelの両方がデータベーステーブルに格納されているデータと一致する必要があります。デフォルトのルールクラスは、静的に宣言されたパターンに依存しているため、ここでは機能しません。

この問題を解決するために、次のURLルールクラスを作成できます。

<?php

namespace app\components;

use yii\web\UrlRuleInterface;
use yii\base\BaseObject;

class CarUrlRule extends BaseObject 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; // this rule does not apply
    }

    public function parseRequest($manager, $request)
    {
        $pathInfo = $request->getPathInfo();
        if (preg_match('%^(\w+)(/(\w+))?$%', $pathInfo, $matches)) {
            // check $matches[1] and $matches[3] to see
            // if they match a manufacturer and a model in the database.
            // If so, set $params['manufacturer'] and/or $params['model']
            // and return ['car/index', $params]
        }
        return false; // this rule does not apply
    }
}

そして、yii\web\UrlManager::$rules構成で新しいルールクラスを使用します。

'rules' => [
    // ...other rules...
    [
        'class' => 'app\components\CarUrlRule',
        // ...configure other properties...
    ],
]

URLの正規化

バージョン2.0.10以降、UrlManagerは、たとえば末尾のスラッシュの有無など、同じURLのバリエーションを処理するためにUrlNormalizerを使用するように構成できます。技術的にはhttps://example.com/pathhttps://example.com/path/は異なるURLであるため、両方で同じコンテンツを提供するとSEOランキングが低下する可能性があります。デフォルトでは、正規化ツールは連続するスラッシュをまとめ、接尾辞に末尾のスラッシュがあるかどうかによって末尾のスラッシュを追加または削除し、永続的なリダイレクトを使用して正規化されたバージョンのURLにリダイレクトします。正規化ツールは、URLマネージャに対してグローバルに構成することも、各ルールに対して個別に構成することもできます。デフォルトでは、各ルールはURLマネージャからの正規化ツールを使用します。UrlRule::$normalizerfalseに設定して、特定のURLルールに対する正規化を無効にできます。

以下に、UrlNormalizerの構成例を示します。

'urlManager' => [
    'enablePrettyUrl' => true,
    'showScriptName' => false,
    'enableStrictParsing' => true,
    'suffix' => '.html',
    'normalizer' => [
        'class' => 'yii\web\UrlNormalizer',
        // use temporary redirection instead of permanent for debugging
        'action' => UrlNormalizer::ACTION_REDIRECT_TEMPORARY,
    ],
    'rules' => [
        // ...other rules...
        [
            'pattern' => 'posts',
            'route' => 'post/index',
            'suffix' => '/',
            'normalizer' => false, // disable normalizer for this rule
        ],
        [
            'pattern' => 'tags',
            'route' => 'tag/index',
            'normalizer' => [
                // do not collapse consecutive slashes for this rule
                'collapseSlashes' => false,
            ],
        ],
    ],
]

注意: デフォルトでは、UrlManager::$normalizerは無効になっています。URLの正規化を有効にするには、明示的に構成する必要があります。

パフォーマンスに関する考慮事項

複雑なWebアプリケーションを開発する場合、リクエストの解析とURLの作成にかかる時間を短縮するためにURLルールを最適化することが重要です。

パラメータ化されたルートを使用することで、URLルールの数を減らすことができ、パフォーマンスを大幅に向上させることができます。

URLの解析または作成時に、URLマネージャは、宣言された順序でURLルールを調べます。したがって、より具体的で、より一般的に使用されるルールを、あまり使用されないルールの前に配置するようにURLルールの順序を調整することを検討できます。

いくつかのURLルールがパターンまたはルートで同じプレフィックスを共有している場合は、yii\web\GroupUrlRuleを使用して、URLマネージャによってグループとしてより効率的に調べられるようにすることを検討できます。これは、アプリケーションがモジュールで構成され、各モジュールがモジュールIDを共通のプレフィックスとして持つ独自のURLルールセットを持っている場合にしばしば当てはまります。

タイプミスを見つけたり、このページを改善する必要があると思われる場合は?
githubで編集 !