Symfonyのルーティングとは
Symfonyのルーティングは、HTTPリクエストのURLをコントローラのアクションに紐づける仕組みです。Laravelと同様に強力なルーティング機能を持ちますが、Symfonyでは定義方法が複数用意されているのが特徴です。
- PHP属性(Attribute)
- YAML
- XML
- PHPファイル
本記事ではよく使われるPHP属性(Attribute)とYAMLを中心に、基本的なルーティングの使い方を解説します。
プロジェクトの準備
まずはSymfonyプロジェクトを作成します。
composer create-project symfony/skeleton my_project
cd my_project
composer require symfony/framework-bundle
composer require symfony/routing
composer require annotations
コントローラを生成します。
php bin/console make:controller ArticleController
PHP属性でルートを定義する(推奨)
Symfony 5.2以降では、PHP 8の#[Attribute]を使ってルートを定義するのが主流です。
<?php
// src/Controller/ArticleController.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class ArticleController extends AbstractController
{
#[Route('/articles', name: 'article_index', methods: ['GET'])]
public function index(): Response
{
return new Response('<h1>記事一覧</h1>');
}
#[Route('/articles/{id}', name: 'article_show', methods: ['GET'])]
public function show(int $id): Response
{
return new Response("<p>記事ID: {$id}</p>");
}
}
ポイント
| 引数 | 説明 |
|---|---|
| 第1引数 | URLパターン |
name | ルートの名前(一意である必要がある) |
methods | 許可するHTTPメソッド |
{id} のように波括弧で囲むとパラメータとして受け取れます。コントローラのメソッド引数名と一致させるだけで自動的にバインドされます。
YAMLでルートを定義する
config/routes.yaml に記述する方法です。設定ファイルでまとめて管理したい場合に便利です。
# config/routes.yaml
article_index:
path: /articles
controller: App\Controller\ArticleController::index
methods: [GET]
article_show:
path: /articles/{id}
controller: App\Controller\ArticleController::show
methods: [GET]
article_create:
path: /articles
controller: App\Controller\ArticleController::create
methods: [POST]
パラメータに制約を加える
URLパラメータに正規表現で制約をつけることができます。たとえば {id} が数値のみを許可する場合は次のように書きます。
PHP属性での制約
#[Route('/articles/{id}', name: 'article_show', requirements: ['id' => '\d+'])]
public function show(int $id): Response
{
return new Response("<p>記事ID: {$id}</p>");
}
YAMLでの制約
article_show:
path: /articles/{id}
controller: App\Controller\ArticleController::show
requirements:
id: '\d+'
/articles/abc のようなリクエストは404になり、/articles/123 だけが受け付けられます。
デフォルト値を設定する
パラメータにデフォルト値を持たせることもできます。
#[Route('/articles/{page}', name: 'article_list', defaults: ['page' => 1])]
public function list(int $page): Response
{
return new Response("<p>{$page}ページ目の記事一覧</p>");
}
/articles にアクセスすると $page は 1 になり、/articles/3 にアクセスすると $page は 3 になります。
名前付きルートでURLを生成する
ルートに名前をつけておくと、テンプレートやコントローラでURLを動的に生成できます。ハードコードを避けられるため、URLを変更しても一箇所だけ直せばよくなります。
コントローラでの生成
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class ArticleController extends AbstractController
{
public function redirectToShow(int $id): Response
{
$url = $this->generateUrl('article_show', ['id' => $id]);
return $this->redirect($url);
}
}
Twigテンプレートでの生成
{# テンプレート内 #}
<a href="{{ path('article_show', { id: article.id }) }}">
{{ article.title }}
</a>
path() は相対URL、url() は絶対URLを生成します。
ルート一覧を確認する
定義したルートの一覧はコンソールコマンドで確認できます。
php bin/console debug:router
出力例:
Name Method Scheme Host Path
article_index GET ANY ANY /articles
article_show GET ANY ANY /articles/{id}
article_create POST ANY ANY /articles
特定のルートの詳細を調べたいときは次のようにします。
php bin/console debug:router article_show
まとめ
Symfonyのルーティングの基本を整理します。
- PHP属性(Attribute) でコントローラに直接ルートを定義するのが現在の主流
{パラメータ}で動的なURLセグメントを受け取れるrequirementsで正規表現による制約が可能defaultsでデフォルト値を設定できる- 名前付きルートを使うと
generateUrl()やpath()でURLを安全に生成できる debug:routerコマンドで定義済みルートを確認できる
LaravelのルーティングはPHPファイルに集約されますが、Symfonyでは属性やYAMLなどチームのスタイルに合わせた形式を選べるのが強みです。まずはPHP属性から試してみましょう。