2015年10月14日水曜日

【Symfony2.7ドキュメント読んだ?】ルーティング

ルートの定義

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

# app/config/routing.yml
app:
    resource: "@AppBundle/Controller/"
    type:     annotation

基本的なルート設定

// src/AppBundle/Controller/MainController.php
// ...
class MainController extends Controller
{
    /**
     * @Route("/")
     */
    public function homepageAction()
    {
        // ...
    }
}

プレースホルダーを使ったルーティング

// src/AppBundle/Controller/BlogController.php

/**
 * @Route("/blog/{page}", defaults={"page" = 1})
 */
public function indexAction($page)
{
    // ...
}
URL Route Parameters
/blog blog {page}=1
/blog/1 blog {page}=1
/blog/2 blog {page}=2

プレースホルダーの値の条件

// src/AppBundle/Controller/BlogController.php
// ...
/**
 * @Route("/blog/{page}", defaults={"page": 1}, requirements={
 *     "page": "\d+"
 * })
 */
public function indexAction($page)
{
    // ...
}

/**
  * @Route("/blog/{slug}")
  */
public function showAction($slug)
{
    // ...
}
URL Route Parameters
/blog/2 blog {page}=2
/blog/my-blog-post blog_show {slug}=my-blog-post
/blog/2-my-blog-post blog_show {slug}=2-my-blog-post

ルーティングは、先に条件にマッチしたメソッドを実行する

// src/AppBundle/Controller/MainController.php
// ...
class MainController extends Controller
{
    /**
     * @Route("/{_locale}", defaults={"_locale": "en"}, requirements={
     *     "_locale": "en|fr"
     * })
     */
    public function homepageAction($_locale)
    {
    }
}
Path Parameters
/ {_locale} = "en"
/en {_locale} = "en"
/fr {_locale} = "fr"
/es won't match this route

HTTPメソッドの指定

/ src/AppBundle/Controller/MainController.php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class MainController extends Controller
{
    /**
     * @Route("/news")
     * @Method("GET")
     */
    public function newsAction()
    {
        // ... display your news
}
    /**
     * @Route("/contact")
     * @Method({"GET", "POST"})
     */
    public function contactFormAction()
    {
        // ... display and process a contact form
    }
}

ホスト名でコントローラを振り分け

# ホスト名を指定
mobile_homepage:
    path:     /
    host:     m.example.com
    defaults: { _controller: AcmeDemoBundle:Main:mobileHomepage }

homepage:
    path:     /
    defaults: { _controller: AcmeDemoBundle:Main:homepage }

# プレースホルダーを用いる場合
projects_homepage:
    path:     /
    host:     "{project_name}.example.com"
    defaults: { _controller: AcmeDemoBundle:Main:mobileHomepage }

homepage:
    path:     /
    defaults: { _controller: AcmeDemoBundle:Main:homepage }

# プレースホルダーを用いる場合(サブドメインを指定する)
mobile_homepage:
    path:     /
    host:     "{subdomain}.example.com"
    defaults:
        _controller: AcmeDemoBundle:Main:mobileHomepage
        subdomain: m
    requirements:
        subdomain: m|mobile

homepage:
    path:     /
    defaults: { _controller: AcmeDemoBundle:Main:homepage }

# パラメータを用いる場合
mobile_homepage:
    path:     /
    host:     "m.{domain}"
    defaults:
        _controller: AcmeDemoBundle:Main:mobileHomepage
        domain: "%domain%"
    requirements:
        domain: "%domain%"

homepage:
    path:  /
    defaults: { _controller: AcmeDemoBundle:Main:homepage }

# ホスト名で読み込むルーティング定義ファイルを指定する
acme_hello:
    resource: "@AcmeHelloBundle/Resources/config/routing.yml"
    host:     "hello.example.com"

高度なルーティングの例

/ 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)
    {
    }
}

# マッチするURLの例
/articles/en/2010/my-post
/articles/en/2010/my-post.rss
/articles/en/2010/my-latest-post.html

コントローラのネーミングパターン

bundle:controller:action
Bundle Controller Class Method Name
AppBundle BlogController showAction

ルーティングのテスト

$crawler = $client->request(
    'GET',
    '/homepage',
    array(),
    array(),
    array('HTTP_HOST' => 'm.' . $client->getContainer()->getParameter('domain'))
);

ルートマッチングの条件指定

contact:
    path:     /contact
    defaults: { _controller: AcmeDemoBundle:Main:contact }
    condition: "context.getMethod() in ['GET', 'HEAD'] and request.headers.get('User-Agent') matches '/firefox/i'"

ルートの確認

# ルートの一覧
php app/console debug:router

#  詳細
php app/console debug:router homepage

# マッチするルートの確認
php app/console router:match /blog/my-latest-post

関連サイト


前の記事 | 次の記事

0 件のコメント:

コメントを投稿