ZetCode

Symfony Route 属性

最后修改时间:2025年3月3日

Symfony Route 属性教程展示了如何在 Symfony 7.2 中使用 Route 属性创建路由。

Symfony

Symfony 是一套可重用的 PHP 组件,也是一个用于 Web 项目的 PHP 框架。Symfony 于 2005 年发布为自由软件。Fabien Potencier 是 Symfony 的最初作者。Symfony 在很大程度上受到了 Spring 框架的启发。

Route 属性

路由是将 URL 路径映射到控制器的机制。例如,/about URL 被映射到 MyControllerabout 方法。

#[Route] 属性是 PHP 8+ 和 Symfony 7.2 中创建路由的现代方法。它取代了旧的 @Route 注解语法,并提供了更好的 IDE 支持和类型安全。其他选项仍然可用,例如 XML 和 YAML 配置文件。

Symfony Route 示例

在下面的示例中,我们使用了 #[Route] 的各种选项。

$ composer create-project symfony/skeleton routeattr "^7.2"
$ cd routeattr

使用 composer,我们创建一个新的 Symfony 7.2 骨架项目。然后我们导航到项目目录。

$ composer require symfony/maker-bundle --dev

我们安装 maker-bundle。请注意,路由属性已内置于 Symfony 7.2 中,无需单独的 annotations 包。

$ php bin/console make:controller MyController

创建了一个 MyController

src/Controller/MyController.php
<?php

declare(strict_types=1);

namespace App\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class MyController extends AbstractController
{
    #[Route(path: '/home', name: 'my_home')]
    public function home(): Response
    {
        return new Response('home', Response::HTTP_OK, ['content-type' => 'text/plain']);
    }

    #[Route(path: '/about', name: 'my_about', methods: ['GET', 'POST'])]
    public function about(Request $request): Response
    {
        $method = $request->getMethod();
        $msg = "about: $method";

        return new Response($msg, Response::HTTP_OK, ['content-type' => 'text/plain']);
    }

    #[Route(path: '/news/{id}', name: 'my_news', requirements: ['id' => '\d+'])]
    public function news(int $id): Response
    {
        $msg = "News $id";

        return new Response($msg, Response::HTTP_OK, ['content-type' => 'text/plain']);
    }
}

MyController 使用 #[Route] 创建了三个路由。

#[Route(path: '/home', name: 'my_home')]
public function home(): Response
{
    return new Response('home', Response::HTTP_OK, ['content-type' => 'text/plain']);
}

在这里,我们使用带命名参数的现代属性语法将 /home 路径映射到 home() 方法。

#[Route(path: '/about', name: 'my_about', methods: ['GET', 'POST'])]
public function about(Request $request): Response
{
    $method = $request->getMethod();
    $msg = "about: $method";

    return new Response($msg, Response::HTTP_OK, ['content-type' => 'text/plain']);
}

通过 methods 选项,我们将请求限制为 GET 和 POST。

#[Route(path: '/news/{id}', name: 'my_news', requirements: ['id' => '\d+'])]
public function news(int $id): Response
{
    $msg = "News $id";

    return new Response($msg, Response::HTTP_OK, ['content-type' => 'text/plain']);
}

通过 requirements 选项和类型提示,我们确保 id 是一个整数。属性语法使用命名参数以提高清晰度。

也可以将 Route 属性放置在控制器类上作为前缀。

$ php bin/console make:controller TestController

我们创建一个新的控制器。

src/Controller/TestController.php
<?php

declare(strict_types=1);

namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

#[Route(path: '/test', name: 'test_')]
class TestController extends AbstractController
{
    #[Route(path: '/car', name: 'car')]
    public function car(): Response
    {
        $msg = 'Testing car';

        return new Response($msg, Response::HTTP_OK, ['content-type' => 'text/plain']);
    }

    #[Route(path: '/book', name: 'book')]
    public function book(): Response
    {
        $msg = 'Testing book';

        return new Response($msg, Response::HTTP_OK, ['content-type' => 'text/plain']);
    }
}

TestController 在类级别使用了带名称前缀的 #[Route]。URL 路径将变为 /test/car/test/book,路由名称分别为 test_cartest_book

$ php bin/console debug:router
--------------- ---------- -------- ------ ------------
Name            Method     Scheme   Host   Path
--------------- ---------- -------- ------ ------------
my_home         ANY        ANY      ANY    /home
my_about        GET|POST   ANY      ANY    /about
my_news         ANY        ANY      ANY    /news/{id}
test_car        ANY        ANY      ANY    /test/car
test_book       ANY        ANY      ANY    /test/book
--------------- ---------- -------- ------ ------------

我们可以使用 bin/console debug:router 命令列出已创建的路由。

运行示例

我们启动服务器,并使用 curl 工具测试创建的路由。

$ php bin/console server:start

我们启动开发服务器。

$ curl localhost:8000/home
home
$ curl -X POST localhost:8000/about
about: POST
$ curl localhost:8000/news/34
News 34
$ curl localhost:8000/test/car
Testing car
$ curl localhost:8000/test/book
Testing book

我们使用 curl 生成请求。

在本教程中,我们使用现代的 #[Route] 属性语法和严格的类型来创建 Symfony 7.2 中的路由。

列出 所有 Symfony 教程