ルーティング


美しい URL は、本格的な Web アプリケーションには絶対に必要です。これは、index.php?article_id=57 のような醜い URL が /read/intro-to-symfony に置き換えられることを意味します。

柔軟性を持つことはさらに重要です。ページの URL を /blog から /news に変更するには何をする必要がありますか?変更を加えるために追跡および更新する必要があるリンクはいくつありますか? Symfony のルーティングを使用すると、これは簡単です。

Symfony Router を使用すると、アプリケーションのさまざまな領域にマッピングするクリエイティブ URL を定義できます。この章を終えると、次のことができるようになります。

  • コントローラーにマップする複雑なルートを作成する

  • テンプレートとコントロールで生成するサーバー内の URL

  • バンドルからルーティング リソースをロードします (他の場所からでも可能)

  • デバッグ ルーティング

##ルーティングの例

A

route は、URL パス (パス) からコントローラー (コントローラー) へのマッピングを指します。たとえば、いくつかの URL: /blog/my-post/blog/all-about-symfony を照合し、「それをクエリしてレンダリングできる」にルートを送信したいとします。コントローラーのブログ投稿「 」。ルーティングは非常に簡単です:

Annotations:// src/AppBundle/Controller/BlogController.phpnamespace AppBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; class BlogController extends Controller{
    /**
     * @Route("/blog/{slug}", name="blog_show")
     */
    public function showAction($slug)
    {
        // ...
    }}
YAML:# app/config/routing.ymlblog_show:
    path:      /blog/{slug}
   defaults:  { _controller: AppBundle:Blog:show }
XML:<!-- app/config/routing.xml --><?xml version="1.0" encoding="UTF-8" ?><routes xmlns="http://symfony.com/schema/routing"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://symfony.com/schema/routing        http://symfony.com/schema/routing/routing-1.0.xsd">     <route id="blog_show" path="/blog/{slug}">
        <default key="_controller">AppBundle:Blog:show</default>
    </route></routes>
PHP:// app/config/routing.phpuse Symfony\Component\Routing\RouteCollection;use Symfony\Component\Routing\Route; $collection = new RouteCollection();$collection->add('blog_show', new Route('/blog/{slug}', array(
    '_controller' => 'AppBundle:Blog:show',))); return $collection;

blog_show ルーティング パターンを定義し、/blog/* のような URL と一致させるために使用し、関連するパラメータまたはワイルドカードには slug を使用します を表し、渡されます。 /blog/my-blog-post のような URL の場合、slug 変数は my-blog-post の値を取得し、コントローラーによって使用されます。 Meishiblog_show は内部名であり、実質的な意味はなく、単なる一意の識別子です。後で、これを使用して URL を生成できます。

アノテーションが気に入らない、または SensioFrameworkExtraBundle に依存したくないという理由でアノテーションを使用したくない場合は、YAML、XML、または PHP を使用することもできます。これらの形式では、

_controller パラメーターは、ルートで指定された URL に対してどのコントローラーを実行する必要があるかを symfony に指示する特別なキーです。 _controllerこの文字列は、論理名と呼ばれます。これはルールに従い、特定の php クラスとメソッド、AppBundle\Controller\BlogController::showAction メソッドを指します。 ######おめでとう!ルートを作成し、コントローラーに接続しました。ここで、/blog/my-post

にアクセスすると、

showAction コントローラーが実行され、$slug 変数は my- と等しくなります。役職## #。 Symfony ルーティングの目標: リクエストされた URL をコントローラーにマップします。この目標に従って、最も複雑な URL のマッピングも簡単にするさまざまなテクニックを学びます。

ルーティング: より詳細な分析

リクエストがアプリケーションに送信されると、そのリクエストにはクライアント リクエストの正確な「リソース」アドレスが含まれます。このアドレスは URL (または URI) と呼ばれ、/contact/blog/read-me などになります。以下は HTTP リクエストの例です:

GET /blog/my-blog-post

symfony ルーティング システムの目的は、URL を解析し、どのコントローラーを呼び出すかを決定することです。全体のプロセスは次のようになります:

  1. リクエストは Symfony のフロントエンド コントローラー (app.php など) によって処理されます。

  2. symfony のコア (カーネル カーネル) では、ルーターがリクエストをチェックする必要があります。

  3. Route は、入力 URL を特定のルートに照合し、実行されるコントローラー情報を含むルート情報を返します。

  4. Symfony カーネルはコントローラーを実行し、最終的に Response オブジェクトを返します。

1466599518_84162_47822_request-flow-1.png

# ルーティングは、入力 URL を特定のツールに変換してコントローラーを実行します。

ルートの作成

Symfony は、単一のルーティング設定ファイルからすべてのルートをアプリケーションにロードします。美しいルーティング構成ファイルは通常、

app/config/routing.yml ですが、アプリケーション構成ファイル (xml または php 形式の構成ファイルを含む) を通じて任意の場所にファイルを配置することもできます。

YAML:# app/config/config.yml
framework:   
# ...
router: { resource: '%kernel.root_dir%/config/routing.yml' }

XML:<!-- app/config/config.xml --><?xml version="1.0" encoding="UTF-8" ?><container xmlns="http://symfony.com/schema/dic/services"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:framework="http://symfony.com/schema/dic/symfony"    xsi:schemaLocation="http://symfony.com/schema/dic/services        http://symfony.com/schema/dic/services/services-1.0.xsd        http://symfony.com/schema/dic/symfony        http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">     <framework:config>
        <!-- ... -->
        <framework:router resource="%kernel.root_dir%/config/routing.xml" />
    </framework:config></container>
PHP:// app/config/config.php$container->loadFromExtension('framework', array(
   // ...    'router' => array(        'resource' => '%kernel.root_dir%/config/routing.php',    ),));
すべてのルートをファイルからロードできますが、追加のルーティング リソースを含めるのが一般的です。これを行うには、外部ルーティング ファイルをメイン ルーティング ファイルに設定します。詳細については、この章を参照してください: 外部ルーティング リソースが含まれています。


基本的なルーティング構成 ¶

ルートを定義するのは簡単で、一般的なアプリケーションには多くのルートが必要です。基本ルートには 2 つの部分が含まれます: path match と defaults array:

Annotations:// src/AppBundle/Controller/MainController.php // ...class MainController extends Controller{
    /**
     * @Route("/")
     */
    public function homepageAction()
    {
        // ...
    }}
YAML:# app/config/routing.yml_welcome:
    path:      /
    defaults:  { _controller: AppBundle:Main:homepage }
XML:<!-- app/config/routing.xml --><?xml version="1.0" encoding="UTF-8" ?><routes xmlns="http://symfony.com/schema/routing"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://symfony.com/schema/routing        http://symfony.com/schema/routing/routing-1.0.xsd">     <route id="_welcome" path="/">
        <default key="_controller">AppBundle:Main:homepage</default>
    </route> </routes>
PHP:// app/config/routing.phpuse Symfony\Component\Routing\RouteCollection;use Symfony\Component\Routing\Route; $collection = new RouteCollection();$collection->add('_welcome', new Route('/', array(
    '_controller' => 'AppBundle:Main:homepage',))); return $collection;

ルートはホームページと一致します ( /) を作成し、AppBundle:Main:homepage コントローラーにマッピングします。 _controller文字列は、Symfony によって実行のために PHP 関数に変換されます。美的プロセスについては、この章 (コントローラーの命名パターン) で簡単に説明します。

パラメータを使用したルーティング ¶

ルーティング システムは、ルートを記述するための多くの興味深い方法をサポートしています。多くのルートには、1 つ以上の「パラメーターまたはワイルドカード」プレースホルダーを含めることができます。

Annotations:// src/AppBundle/Controller/BlogController.php // ...class BlogController extends Controller{
    /**
     * @Route("/blog/{slug}")
     */
    public function showAction($slug)
    {
        // ...
    }}
YAML:# app/config/routing.ymlblog_show:
    path:      /blog/{slug}
    defaults:  { _controller: AppBundle:Blog:show }
XML:<!-- app/config/routing.xml --><?xml version="1.0" encoding="UTF-8" ?><routes xmlns="http://symfony.com/schema/routing"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://symfony.com/schema/routing        http://symfony.com/schema/routing/routing-1.0.xsd">     <route id="blog_show" path="/blog/{slug}">
        <default key="_controller">AppBundle:Blog:show</default>
    </route></routes>
PHP:// app/config/routing.phpuse Symfony\Component\Routing\RouteCollection;use Symfony\Component\Routing\Route; $collection = new RouteCollection();$collection->add('blog_show', new Route('/blog/{slug}', array(
    '_controller' => 'AppBundle:Blog:show',))); return $collection;


きれいなパスは、任意の /blog/* URL に一致します。さらに良いのは、美しい {slug} プレースホルダーが自動的にコントローラーに一致することです。つまり、URL が /blog/hello-world の場合、コントローラーの $slug 変数の値は hello-world になります。これは、ブログ投稿タイトルの文字列を照合するために使用できます。

ただし、デフォルトではすべてのプレースホルダーが必要であるため、この方法でルーティングすると /blog のような URL とは一致しません。もちろん、プレースホルダー (パラメーター) 値を defaults 配列に追加することでこれを変更することもできます。

{ワイルドカード} 条件を追加します

作成したルートをざっと見てみましょう:

Annotations:// src/AppBundle/Controller/BlogController.php // ...class BlogController extends Controller{
    /**
     * @Route("/blog/{page}", defaults={"page" = 1})
     */
    public function indexAction($page)
    {
        // ...
    }     /**
     * @Route("/blog/{slug}")
     */
    public function showAction($slug)
    {
        // ...
    }}
YAML:# app/config/routing.ymlblog:
    path:      /blog/{page}
    defaults:  { _controller: AppBundle:Blog:index, page: 1 }blog_show:
    path:      /blog/{slug}
    defaults:  { _controller: AppBundle:Blog:show }
XML:<!-- app/config/routing.xml --><?xml version="1.0" encoding="UTF-8" ?><routes xmlns="http://symfony.com/schema/routing"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://symfony.com/schema/routing        http://symfony.com/schema/routing/routing-1.0.xsd">     <route id="blog" path="/blog/{page}">
        <default key="_controller">AppBundle:Blog:index</default>
        <default key="page">1</default>
    </route>     <route id="blog_show" path="/blog/{slug}">
        <default key="_controller">AppBundle:Blog:show</default>
    </route></routes>
PHP:// app/config/routing.phpuse Symfony\Component\Routing\RouteCollection;use Symfony\Component\Routing\Route; $collection = new RouteCollection();$collection->add('blog', new Route('/blog/{page}', array(
    '_controller' => 'AppBundle:Blog:index',
    'page'        => 1,))); $collection->add('blog_show', new Route('/blog/{show}', array(
    '_controller' => 'AppBundle:Blog:show',))); return $collection;


問題を見つけられますか? ?どちらのルートも /blog/* のような URL に一致します。 symfony ルーティングは常に、最初に一致する (ブログ) ルートを選択します。つまり、blog_show ルートは常に一致します。対照的に、/blog/my-blog-post のような URL は、最初の (blog) ルートと一致し、my-blog-post の値を返します。 {page} パラメータに与えられます。

URLルートパラメータ/blog/2blog_list$page##/blog/my-blog-post =

{wildcard} にデフォルト値を与える

高度なルーティングの例

Symfony では、強力なルーティング構造を作成して次のことを実現できます。あなたが必要とするすべて。ルーティング システムがいかに柔軟であるかを示す例を次に示します。

Annotations:// src/AppBundle/Controller/ArticleController.php // ...class ArticleController extends Controller{
    /**
     * @Route(
     *     "/articles/{_locale}/{year}/{title}.{_format}",
     *     defaults={"_format": "html"},
     *     requirements={
     *         "_locale": "en|fr",
     *         "_format": "html|rss",
     *         "year": "\d+"
     *     }
     * )
     */
    public function showAction($_locale, $year, $title)
    {
    }}
YAML:# app/config/routing.ymlarticle_show:
  path:     /articles/{_locale}/{year}/{title}.{_format}
  defaults: { _controller: AppBundle:Article:show, _format: html }
  requirements:
      _locale:  en|fr
      _format:  html|rss
      year:     \d+
XML:<!-- app/config/routing.xml --><?xml version="1.0" encoding="UTF-8" ?><routes xmlns="http://symfony.com/schema/routing"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://symfony.com/schema/routing        http://symfony.com/schema/routing/routing-1.0.xsd">     <route id="article_show"        path="/articles/{_locale}/{year}/{title}.{_format}">         <default key="_controller">AppBundle:Article:show</default>
        <default key="_format">html</default>
        <requirement key="_locale">en|fr</requirement>
        <requirement key="_format">html|rss</requirement>
        <requirement key="year">\d+</requirement>     </route></routes>
PHP:// app/config/routing.phpuse Symfony\Component\Routing\RouteCollection;use Symfony\Component\Routing\Route; $collection = new RouteCollection();$collection->add(
    'article_show',
    new Route('/articles/{_locale}/{year}/{title}.{_format}', array(
        '_controller' => 'AppBundle:Article:show',
        '_format'     => 'html',
    ), array(
        '_locale' => 'en|fr',
        '_format' => 'html|rss',
        'year'    => '\d+',
    ))); return $collection;

ご覧のとおり、美しいルーティングは、{_locale} を満たす URL の一部にのみ一致します。 en または fr) および {year} は数値です。このルートでは、ピリオドを使用して 2 つのプレースホルダーを区切ることができることも示します。上記のルートで一致する URL は次のとおりです:

  • ##/articles/ja/2010/my-post

  • /articles/fr/2010/my-post.rss

  • ##/articles/en/2013/my-latest-post.html
特別な _format ルート パラメータ

この例では、特別な _format

ルーティングも強調表示します。パラメーター。このパラメータを使用すると、一致する値が

Request オブジェクトの「リクエスト形式」になります。 最終的に、リクエスト形式は「レスポンスの Content-Type

の設定」などの場所で使用されます (たとえば、

json リクエスト形式は次のように変換されます) application/ jsonContent-Type)。これをコントローラーで使用して、さまざまな _format 値に基づいてさまざまなテンプレートをレンダリングすることもできます。 _format パラメーターは、同じコンテンツを異なる形式でレンダリングするための非常に強力な方法です。 symfony3.0 より前のバージョンでは、「_format

」という名前のパラメータを追加することで、リクエスト (オブジェクト) のフォーマットパラメータ (

_format) をオーバーライドできます。パラメータ (例: /foo/bar?_format=json)。この動作の悪用は悪い習慣とみなされ、プログラムを symfony3 にアップグレードすることが「非常に複雑」になります。

#ルートの特定の部分を「グローバル構成」にしたい場合があります。 symfony はサービスコンテナパラメータを使用してこれを行うことができます。詳細については、「ルーティングでサービス コンテナ パラメータを使用する方法」を参照してください。

特別なルーティング パラメータ ¶

ご覧のとおり、すべてのルーティング パラメータまたはデフォルト値は、コントローラ メソッドのパラメータとして使用できます。さらに、3 つのパラメータが特別です。それぞれがアプリケーションに独自の機能を追加します。

  • #_controller
  • #ご覧のとおり、このパラメータは、どのパラメータがどれであるかを決定するために使用されます。 「ルートが一致した場合」に実行するコントローラ。
  • _format
  • は、リクエスト形式 (リクエスト形式。詳細) を設定するために使用されます。
  • _locale
  • 要求されたロケールを設定するために使用されます (詳細)。
コントローラーの命名パターン

YAML、XML、または PHP ルート構成を使用する場合、各ルートには、ルートが一致したときにどのコントローラーを実行するかを示す

_controller パラメーターが必要です。このパラメータは、論理コントローラ名と呼ばれる単純な文字列パターンを使用します。これは、Symfony が特定の PHP メソッドまたはクラスをマップするために使用されます。このパターンには、コロンで区切られた 3 つの部分があります。

bundle:controller:action

_controller と仮定します。値は AppBundle:Blog:show で、意味は次のとおりです:

= 2
blog_show $スラッグ私のブログ投稿
##Bundle##AppBundle

コントローラーは次のようになります:

// src/AppBundle/Controller/BlogController.phpnamespace AppBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; class BlogController extends Controller{
    public function showAction($slug)
    {
        // ...
    }}

Symfony が Blog (Blog) にクラス名として文字列 Controller を追加したことに注意してください。 =>BlogController)、文字列 Action をメソッド名として追加します (show=>showAction)。

FQCN クラス名とメソッド AppBundle\Controller\BlogController::showAction を使用してこのクラスを指定することもできます。ただし、いくつかの単純な命名規則に従えば、論理名はよりシンプルかつ柔軟になります。

論理名と FQCN クラス名の使用に加えて、Symfony はコントローラーを指定する 3 番目の方法もサポートしています。このアプローチはコロンでのみ区切られ (例: service_name:indexAction)、コントローラーをサービスとして参照します (コントローラーをサービスとして定義する方法を参照)。

ルーティング パラメータとコントローラ パラメータ ¶

ルーティング パラメータ ({slug} など) はパラメータとして使用されるため、非常に重要です。コントローラー メソッドの場合:

public function showAction($slug){
  // ...}

実際には、defaults セットはパラメーター値をフォーム配列にマージします。配列内の各キーはコントローラーのパラメーターとして使用されます。

つまり、コントローラー メソッドのパラメーターごとに、Symfony2 はその名前に基づいてルート パラメーターを検索し、その値をパラメーターとしてコントローラーにポイントします。次の変数は (何らかの方法で) showAction() メソッドのパラメータとして使用されます:

  • $_locale

  • $year

  • $title

  • $_format

  • $_controller

  • $_route

プレースホルダーと defaults セットは、$_controller 変数であってもマージされます。詳細については、「コントローラーとして – ルート パラメーターをコントローラーに渡す」を参照してください。

特定の $ _route変数、その値を使用することもできます。は、一致したルート名です。

ルートで追加情報を定義し、コントローラーでそれにアクセスすることもできます。詳細については、「ルートからコントローラーに追加情報を渡す方法」を参照してください。

URL の生成¶

ルーティング システムは、URL の生成にも使用されます。実際には、ルーティングは双方向のシステムです。URL をコントローラー パラメーターにマッピングし、ルート パラメーターを URL にマッピングし直します。 match() メソッドと generate() メソッドは、この双方向システムを構成します。前の blog_show の例を使用すると:

$params = $this->get('router')->match('/blog/my-blog-post');
// array(
//     'slug'        => 'my-blog-post',
//  '_controller' => 'AppBundle:Blog:show',
// ) 
$uri = $this->get('router')->generate('blog_show', array(
  'slug' => 'my-blog-post'));
// /blog/my-blog-post

URL を生成するには、ルートの名前 (blog_show など) とワイルドカード (たとえば、 スラッグ = 私のブログ投稿 )。この情報を使用すると、任意の URL を簡単に生成できます:

class MainController extends Controller{
    public function showAction($slug)
    {
        // ...         $url = $this->generateUrl(
            'blog_show',
            array('slug' => 'my-blog-post')
        );
    }}

コントローラーでは、symfony の親クラスであるコントローラーを継承しない場合、generateUrl()Shortcut を使用できません。メソッドですが、ルーターの generate()Service メソッドを使用することもできます:

$url = $this->container->get('router')->generate(
    'blog_show',
    array('slug' => 'my-blog-post'));

次のセクションでは、テンプレートで URL アドレスを生成する方法を学習します。

アプリケーション フロントエンドで Ajax リクエストを使用する場合は、ルーティング設定に基づいて JavaScript で URL を生成することができます。 FOSJsRoutingBundle を使用すると、次のことが可能になります。

var url = Routing.generate(
    'blog_show',
    {"slug": 'my-blog-post'});

詳細については、このバンドル ドキュメントをお読みください。

クエリ文字列を使用した URL の生成

この generate メソッドでは、ワイルドカード配列を使用して URL を生成します。ただし、追加のキーと値のペアが追加された場合は、新しい URL を生成するためのクエリ文字列として追加されます。

$this->get('router')->generate('blog', array(
    'page' => 2,
    'category' => 'Symfony'));// /blog/2?category=Symfony

Generate URL in template

Whenアプリケーション ページ間を接続する場合、これを行う最も一般的な場所は、テンプレートから URL を生成することです。これを行うことは実際には前と同じですが、テンプレート ヘルパー関数を使用します。

Twig:<a href="{{ path('blog_show', {'slug': 'my-blog-post'}) }}">
  Read this blog post.
</a>
php:<a href="<?php echo $view['router']->path('blog_show', array(
    'slug' => 'my-blog-post',)) ?>">
    Read this blog post.
</a>

絶対 URL を生成する

デフォルトでは、ルーターは相対 URL (たとえば、 /ブログとして)。コントローラーでは、generateUrl() メソッドの 3 番目のパラメーターを UrlGeneratorInterface::ABSOLUTE_URL に設定するのは非常に簡単です。

use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
 $this->generateUrl('blog_show', array('slug' => 'my-blog-post'), UrlGeneratorInterface::ABSOLUTE_URL);
// http://www.example.com/blog/my-blog-post

テンプレート エンジン Twig では、path() 関数 (相対 URL を生成) の代わりに url() 関数 (絶対 URL を生成) を使用します。 . URL)。 php では、UrlGeneratorInterface::ABSOLUTE_URL:

Twig:<a href="{{ url('blog_show', {'slug': 'my-blog-post'}) }}">
  Read this blog post.
</a>
php:<a href="<?php echo $view['router']->url('blog_show', array(
    'slug' => 'my-blog-post',)) ?>">
    Read this blog post.
</a>

当生成一个绝对URL链接时,所使用的主机自动检测当前使用的Request对象。当生成从web环境外的绝对URL(例如一个控制台命令)这是行不通的。请参见 如何从控制台生成URL 来学习如何解决这个问题。


概要 ¶

ルーティングは、受信リクエストをリクエストの処理に使用される URL にマップする URL です。コントローラー関数のシステムです。 。これにより、美しい URL を指定し、アプリケーションの機能を URL から「切り離す」ことができます。ルーティングは双方向のメカニズムであるため、URL の生成にも使用できます。

続行! ¶

ルーティング、確認されました!さて、コントローラーの電源ブロックを解除してください。

Controller クラスメソッド名
BlogController showAction