Symfony4中国語のドキュメント:ルーティング

ルーティング

プリティURLは深刻なWebアプリケーションです。これは、そのような意味。必要とindex.php?article_id=57 、このような醜いURLであることを/read/intro-to-symfony置き換え。

柔軟性がより重要である。あなたが必要な場合は/blog変更/news 、あなたはsymfonyのルーティングを使用している場合、何が?あなたはこの変更を行うために更新するために検索してリンクする必要がありますどのくらい?行われる必要がある、との変化は非常に簡単になります。

ルートを作成する

あなたは、ルーティングのために完全に一致する場合は、ルートは、コントローラへのURLからマップされている/blogのような任意のより多くの試合と加えて/blog/my-postおよび/blog/all-about-symfony動的ルーティングURLを。

ルーティングはYAML、XML、PHPで利用できます。すべてのフォーマットで同じ機能とパフォーマンスが得られますので、好きなフォーマットを選択できます。PHPアノテーションを選択した場合は、アプリケーションでこのコマンドを一度実行してサポートします。 :

$ composer require annotations

これで経路を設定できます:

注釈

// src/Controller/BlogController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class BlogController extends AbstractController
{
    /**
     * Matches /blog exactly
     *
     * @Route("/blog", name="blog_list")
     */
    public function list()
    {
        // ...
    }

    /**
     * Matches /blog/*
     *
     * @Route("/blog/{slug}", name="blog_show")
     */
    public function show($slug)
    {
        // $slug will equal the dynamic part of the URL
        // e.g. at /blog/yay-routing, then $slug='yay-routing'

        // ...
    }
}

YAML

# config/routes.yaml
blog_list:
    path:     /blog
    controller: App\Controller\BlogController::list

blog_show:
    path:     /blog/{slug}
    controller: App\Controller\BlogController::show
    

XML

<!- config/routes.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_list" controller="App\Controller\BlogController::list" path="/blog" >
        <!- settings ->
    </route>

    <route id="blog_show" controller="App\Controller\BlogController::show" path="/blog/{slug}">
        <!- settings ->
    </route>
</routes>

PHP

// config/routes.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use App\Controller\BlogController;

$routes = new RouteCollection();
$routes->add('blog_list', new Route('/blog', array(
    '_controller' => [BlogController::class, 'list']
)));
$routes->add('blog_show', new Route('/blog/{slug}', array(
    '_controller' => [BlogController::class, 'show']
)));

return $routes;

これらの2つのルートのおかげで:

  • ユーザアクセス場合/blog 、及び第一の整合へのルートlist()実行されます。
  • ユーザアクセス場合/blog/* 、第二試合とへのルートshow()実行される、なぜならルーティングパス/blog/{slug}そう$slug変数は、値が一致に渡されるshow() 。例えば、ユーザアクセス/blog/yay-routing 、そして$slug等しくなりますyay-routing

パスをルーティングするたびにすることはあり{placeholder}一部がワイルドカードになると:それはあなたが今という名前のコントローラを持っている任意の値と一致します。 $placeholderパラメータ(パラメータ名が一致し、ワイルドカードなければなりません)。

:各ルートは、内部名があるblog_listblog_showこれらは、(限り、それぞれがユニークであるように)何もすることができ、後であなたがURLを生成するためにそれらを使用する特別な意味を必要としません..

他のフォーマットでのルーティング

@Route上記の各メソッドは、アノテーションと呼ばれています。あなたはYAML、XMLやPHPの設定のルーティングを使用する場合は、何の問題が!単純に(例えばのための新しいルートファイルを作成しないことをroutes.xml )、symfonyは自動的にそれを使用します。

ローカライズされたルーティング(i18n)

ルーティングは、各ゾーンに固有のパスをローカルに提供することができます.Symfonyは、重複することなくローカライズされたルートを宣言する簡単な方法を提供します。

注釈

// src/Controller/CompanyController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class CompanyController extends AbstractController
{
    /**
     * @Route({
     *     "nl": "/over-ons",
     *     "en": "/about-us"
     * }, name="about_us")
     */
    public function about()
    {
        // ...
    }
}

YAML

# config/routes.yaml
about_us:
    path:
        nl: /over-ons
        en: /about-us
    controller: App\Controller\CompanyController::about
    

XML

<!- config/routes.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="about_us" controller="App\Controller\CompanyController::about">
        <path locale="nl">/over-ons</path>
        <path locale="en">/about-us</path>
    </route>
</routes>

PHP

// config/routes.php
namespace Symfony\Component\Routing\Loader\Configurator;

return function (RoutingConfigurator $routes) {
    $routes->add('about_us', ['nl' => '/over-ons', 'en' => '/about-us'])
        ->controller('App\Controller\CompanyController::about');
};

ローカライズされたルートが一致すると、Symfonyはリクエスト中にどの地域のルーティング設定を使用するかを自動的に特定します。この方法でルートを定義すると、登録が重複する必要がなくなり、矛盾した定義によるエラーのリスクを最小限に抑えます。

国際化されたアプリケーションでは、すべてのルートに接頭辞を追加することが一般的な要件です。これは、各ロケールに異なるパス接頭辞を定義することによって行うことができます(デフォルト言語にヌル接頭辞を設定できます)。

YAML

# config/routes/annotations.yaml
controllers:
    resource: '../../src/Controller/'
    type: annotation
    prefix:
        en: '' # don't prefix URLs for English, the default locale
        nl: '/nl'
        

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

、想像blog_listルートが含まれているブログのトピックページのリストが含まれます/blog/2および/blog/3あなたはパス変更した場合、ページのURLをステップ2と3 /blog/{page} 、あなた問題が発生する:

  • blog_list: /blog/{page}マッチします/blog/* ;
  • blog_show: /blog/{slug}まだ一致します/blog/*

二つの経路が同じURLと一致した場合、意味し、勝利により、残念ながら。最初の道をロード/blog/yay-routing一致するblog_list

この問題を解決するには、追加{page}数字のためにのみ、ワイルドカードの試合を:

注釈

// src/Controller/BlogController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class BlogController extends AbstractController
{
    /**
     * @Route("/blog/{page}", name="blog_list", requirements={"page"="\d+"})
     */
    public function list($page)
    {
        // ...
    }

    /**
     * @Route("/blog/{slug}", name="blog_show")
     */
    public function show($slug)
    {
        // ...
    }
}

YAML

# config/routes.yaml
blog_list:
    path:      /blog/{page}
    controller: App\Controller\BlogController::list
    requirements:
        page: '\d+'

blog_show:
    # ...

XML

<!- config/routes.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_list" path="/blog/{page}" controller="App\Controller\BlogController::list">
        <requirement key="page">\d+</requirement>
    </route>

    <!- ... ->
</routes>

PHP

// config/routes.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use App\Controller\BlogController;

$routes = new RouteCollection();
$routes->add('blog_list', new Route('/blog/{page}', array(
    '_controller' => [BlogController::class, 'list'],
), array(
    'page' => '\d+'
)));

// ...

return $routes;

\d+任意の長さの一致である今のデジタル正規表現です。:

URL ルート パラメータ
/ blog / 2 Blog_list $ page = 2
/ blog / yay-routing Blog_show $ slug = yay-routing

ご希望の場合は、各プレースホルダの構文を使用することができます{placeholder_name<requirements>}複雑な要件は、それがルートの可読性を削減する場合には、この機能は、よりコンパクトな構成が可能となりますが、:

注釈

// src/Controller/BlogController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class BlogController extends AbstractController
{
    /**
     * @Route("/blog/{page<\d+>}", name="blog_list")
     */
    public function list($page)
    {
        // ...
    }
}

YAML

# config/routes.yaml
blog_list:
    path:      /blog/{page<\d+>}
    controller: App\Controller\BlogController::list

XML

<!- config/routes.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_list" path="/blog/{page<\d+>}"
           controller="App\Controller\BlogController::list" />

    <!- ... ->
</routes>

PHP

// config/routes.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use App\Controller\BlogController;

$routes = new RouteCollection();
$routes->add('blog_list', new Route('/blog/{page<\d+>}', array(
    '_controller' => [BlogController::class, 'list'],
)));

// ...

return $routes;

(例えばHTTPメソッド、ホスト名、および動的な式など)追加のルーティング条件を参照ルート要件を定義する方法

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

前の例では、 blog_listパスは/blog/{page} 。ユーザアクセス場合/blog/1 、一致させることができる。ユーザがアクセスした場合/blog 、ちょうどルーティング経路を{}プレースホルダを追加する。一致しません、値を持たなければなりません。

したがって、ユーザーの訪問時に/blogどのようにするとき、 blog_list追加することによって、それを再び一致? 默认値:

注釈

// src/Controller/BlogController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class BlogController extends AbstractController
{
    /**
     * @Route("/blog/{page}", name="blog_list", requirements={"page"="\d+"})
     */
    public function list($page = 1)
    {
        // ...
    }
}

YAML

# config/routes.yaml
blog_list:
    path:      /blog/{page}
    controller: App\Controller\BlogController::list
    defaults:
        page: 1
    requirements:
        page: '\d+'

blog_show:
    # ...
    

XML

<!- config/routes.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_list" path="/blog/{page}" controller="App\Controller\BlogController::list">
        <default key="page">1</default>

        <requirement key="page">\d+</requirement>
    </route>

    <!- ... ->
</routes>

PHP

// config/routes.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use App\Controller\BlogController;

$routes = new RouteCollection();
$routes->add('blog_list', new Route(
    '/blog/{page}',
    array(
        '_controller' => [BlogController::class, 'list'],
        'page'        => 1,
    ),
    array(
        'page' => '\d+'
    )
));

// ...

return $routes;

今、ユーザーが訪問するとき/blog時間は、 blog_listルートが一致し、 $pageルーティングパラメータは、の値がデフォルトになります1

ワイルドカードとして{条件}、構文を使用{placeholder_name?default_value}また、条件互換性のある、この関数のインライン展開の各プレースホルダ文字のインラインデフォルト値にすることができ、あなたが、プレースホルダ、インラインで次のことができます。

注釈

// src/Controller/BlogController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class BlogController extends AbstractController
{
    /**
     * @Route("/blog/{page<\d+>?1}", name="blog_list")
     */
    public function list($page)
    {
        // ...
    }
}

YAML

# config/routes.yaml
blog_list:
    path:      /blog/{page<\d+>?1}
    controller: App\Controller\BlogController::list

XML

<!- config/routes.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_list" path="/blog/{page <\d+>?1}"
           controller="App\Controller\BlogController::list" />

    <!- ... ->
</routes>

PHP

// config/routes.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use App\Controller\BlogController;

$routes = new RouteCollection();
$routes->add('blog_list', new Route('/blog/{page<\d+>?1}', array(
    '_controller' => [BlogController::class, 'list'],
)));

// ...

return $routes;

プレースホルダ変数の値ならばnull変数は、あなたが最後にワイルドカードを追加する必要がある?文字(例えば/blog/{page?} )。

すべてのルーティングリスト

アプリケーションが大きくなると、最終的に多数のルートが定義されます!すべてを見るには、次のコマンドを実行します。

$ php bin/console debug:router

- - -
 Name                           Method   Path
- - -
 app_lucky_number                 ANY    /lucky/number/{max}
 ...
- - 

高度なルーティングの例

上級の例をご覧ください:

注釈

// src/Controller/ArticleController.php

// ...
class ArticleController extends AbstractController
{
    /**
     * @Route(
     *     "/articles/{_locale}/{year}/{slug}.{_format}",
     *     defaults={"_format": "html"},
     *     requirements={
     *         "_locale": "en|fr",
     *         "_format": "html|rss",
     *         "year": "\d+"
     *     }
     * )
     */
    public function show($_locale, $year, $slug)
    {
    }
}

YAML

# config/routes.yaml
article_show:
  path:     /articles/{_locale}/{year}/{slug}.{_format}
  controller: App\Controller\ArticleController::show
  defaults:
      _format: html
  requirements:
      _locale:  en|fr
      _format:  html|rss
      year:     \d+

XML

<!- config/routes.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}/{slug}.{_format}"
        controller="App\Controller\ArticleController::show">

        <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

// config/routes.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use App\Controller\ArticleController;

$routes = new RouteCollection();
$routes->add(
    'article_show',
    new Route('/articles/{_locale}/{year}/{slug}.{_format}', array(
        '_controller' => [ArticleController::class, 'show'],
        '_format'     => 'html',
    ), array(
        '_locale' => 'en|fr',
        '_format' => 'html|rss',
        'year'    => '\d+',
    ))
);

return $routes;

あなたは、URLときにのみ、見ることができるように{_locale}部分があるenまたはfr{year}デジタルで、このルートが一致します。例はまた、プレースホルダの間で使用する方法を示しています.数置き換え/以下を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形式が変換されたものの一種Content-Typeapplication/json

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

ご覧のように、最終的に各ルーティングパラメータまたはデフォルト値をコントローラメソッドのパラメータとして使用することができます。また、4つの特別なパラメータがあります。各パラメータには、アプリケーション固有の機能があります。

_controller

経路が合ったときを決定するために使用されるコントローラ

_format

設定要求フォーマット( 続きを読みます

_fragment

フラグメント識別子、およびURLの最後にオプションの一部を設定するための#文書の特定の部分を識別するために使用される文字の始まり。

_locale

リクエストに応じて領域を設定する( 続きを読みます

予告編スラッシュリダイレクトURL

歴史的に、URLは、UNIXの規則に従って、末尾にスラッシュ(例:追加するパスですhttps://example.com/foo/ (削除の参照はファイルとしてスラッシュするとき、) https://example.com/foo 2つのURLに異なるコンテンツを提供することはできますが、2つのURLを同じURLとして扱い、それらの間をリダイレクトするのが一般的です。

symfonyは、このロジックの後に、スラッシュ付きのURLとスラッシュなしのURLをリダイレクトします(ただし、GETリクエストとHEADリクエストの場合のみ)。

ルートパス 要求されたURLが/ fooの場合 要求されたURLが/ foo /
/ foo それは(200ステータス応答) / fooに301リダイレクトさせる
/ foo / これは、/ foo / それは(200ステータス応答)

各パスのためのアプリケーション(場合/foo及び/foo/別のルートを定義)、それは自動的にリダイレクトに発生し、常に正しいルートとは一致しません。

Symfony4.1から導入/foo/ために/foo自動的に、リリース前に404応答301 symfonyのリダイレクト。

コントローラーの名前付けモード

ルートコントローラフォーマットは非常に単純ですCONTROLLER_CLASS::METHOD

コントローラクラスの__invoke()メソッドとして実装されているアクションを参照するには、メソッド名を渡す必要はありませんが、完全修飾クラス名(例:AppControllerBlogController)を使用できます。

URLを生成する

ルーティングシステムはURLを生成することもできます。実際、ルーティングは、双方向システムです。つまり、URLをコントローラにマッピングし、URLに戻すことです。

URLを生成するには、(たとえば、ルート名開発する必要がありblog_show )と(そのように使用されるルートのパスとして、任意のワイルドカードslug = my-blog-post 、あなたが簡単に任意のURLを生成することができ、この情報を使用します):

class MainController extends AbstractController
{
    public function show($slug)
    {
        // ...

        // /blog/my-blog-post
        $url = $this->generateUrl(
            'blog_show',
            array('slug' => 'my-blog-post')
        );
    }
}

あなたは、に、サービスからURLを生成する必要がある場合UrlGeneratorInterfaceのサービス。

// src/Service/SomeService.php

use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class SomeService
{
    private $router;

    public function __construct(UrlGeneratorInterface $router)
    {
        $this->router = $router;
    }

    public function someMethod()
    {
        $url = $this->router->generate(
            'blog_show',
            array('slug' => 'my-blog-post')
        );
        // ...
    }
}

クエリ文字列を使用してURLを生成する

generate()メソッドは、ワイルドカードURIを生成するための配列を使用しています。しかし、あなたは追加の値を渡した場合、彼らは、クエリ文字列としてURIに追加されます。

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

ローカライズされたURLを生成する

ローカリゼーションをルーティングするとき、symfonyはパラメータの配列を渡す必要があり、URL異なるロケールを生成するためのURLを生成するために、現在のデフォルトのリクエスト領域を使用。 _locale

$this->router->generate('about_us', array(
    '_locale' => 'nl',
));
// generates: /over-ons

テンプレートからURLを生成する

小枝でURLを生成するには、次を参照してください。 テンプレートセクションを 。あなたはJavaScriptでURLを生成する必要がある場合、参照JavaScriptでのルーティングのURLを生成する方法

絶対URLを生成する

デフォルトでは、生成された経路の相対URL(例えば/blog )コントローラで、。 UrlGeneratorInterface::ABSOLUTE_URLに渡さgenerateUrl()第三の方法のパラメータ:

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

現在のリクエストオブジェクトを使用して、絶対URLを生成する際に使用されるホストが自動的に検出されます。(コンソールコマンドなどで)Webコンテキスト外から絶対URLを生成する場合、これは機能しません。この問題を解決する方法を学びます。

エラーの除去

ルーティングを使用する際に発生する可能性がある一般的なエラーは次のとおりです。

コントローラ "AppControllerBlogController :: show()"では、 "$ slug"引数の値を指定する必要があります。

あなたは、(例えば、コントローラのメソッドのパラメータがある場合$slug )に発生します:


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

あなたは、ルートない{slug}ワイルドカード(例えば/blog/show )あなたのルーティングパスを増やす。 {slug}/blog/show/{slug}またはデフォルトのパラメータ値に設定(例えば、 $slug = null

ルート "blog_show"のURLを生成するために必須のパラメータがいくつかあります( "slug")。

これは、あなたが生成しようとしていることを意味blog_showルート生成するときに、ルートのURLを、しかし、あなたは(ルーティングパスの{スラグ}ワイルドカードがありますので、これは必要である)スラグ値を渡すことはありません。この問題を解決するには、合格してくださいslug値を:

$this->generateUrl('blog_show', array('slug' => 'slug-value'));

// or, in Twig
// {{ path('blog_show', {'slug': 'slug-value'}) }}

元のリンク