跳到内容

控制器

编辑此页

控制器是一个您创建的 PHP 函数,它从 Request 对象读取信息,并创建和返回一个 Response 对象。响应可以是 HTML 页面、JSON、XML、文件下载、重定向、404 错误或任何其他内容。控制器运行您的应用程序需要渲染页面内容的任何任意逻辑。

提示

如果您尚未创建您的第一个工作页面,请查看 在 Symfony 中创建您的第一个页面,然后再回来!

一个基本的控制器

虽然控制器可以是任何 PHP 可调用对象(函数、对象方法或 Closure),但控制器通常是控制器类中的一个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// src/Controller/LuckyController.php
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class LuckyController
{
    #[Route('/lucky/number/{max}', name: 'app_lucky_number')]
    public function number(int $max): Response
    {
        $number = random_int(0, $max);

        return new Response(
            '<html><body>Lucky number: '.$number.'</body></html>'
        );
    }
}

控制器是 number() 方法,它位于控制器类 LuckyController 中。

这个控制器非常简单

  • 第 2 行:Symfony 利用 PHP 的命名空间功能来命名整个控制器类。
  • 第 4 行:Symfony 再次利用 PHP 的命名空间功能:use 关键字导入 Response 类,控制器必须返回该类。
  • 第 7 行:该类在技术上可以被命名为任何名称,但按照惯例,它以 Controller 为后缀。
  • 第 10 行:由于 路由中的通配符 {max},操作方法允许有一个 $max 参数。
  • 第 14 行:控制器创建并返回一个 Response 对象。

将 URL 映射到控制器

为了查看此控制器的结果,您需要通过路由将 URL 映射到它。这在上面通过 路由属性 #[Route('/lucky/number/{max}')] 完成。

要查看您的页面,请在浏览器中转到此 URL:http://127.0.0.1:8000/lucky/number/100

有关路由的更多信息,请参阅 路由

基础控制器类 & 服务

为了辅助开发,Symfony 提供了一个可选的基础控制器类,名为 AbstractController。它可以被扩展以访问辅助方法。

在您的控制器类的顶部添加 use 语句,然后修改 LuckyController 以扩展它

1
2
3
4
5
6
7
8
9
10
// src/Controller/LuckyController.php
  namespace App\Controller;

+ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

- class LuckyController
+ class LuckyController extends AbstractController
  {
      // ...
  }

就是这样!您现在可以访问诸如 $this->render() 等方法以及您将在接下来了解的许多其他方法。

生成 URL

generateUrl() 方法只是一个辅助方法,用于生成给定路由的 URL

1
$url = $this->generateUrl('app_lucky_number', ['max' => 10]);

重定向

如果您想将用户重定向到另一个页面,请使用 redirectToRoute()redirect() 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;

// ...
public function index(): RedirectResponse
{
    // redirects to the "homepage" route
    return $this->redirectToRoute('homepage');

    // redirectToRoute is a shortcut for:
    // return new RedirectResponse($this->generateUrl('homepage'));

    // does a permanent HTTP 301 redirect
    return $this->redirectToRoute('homepage', [], 301);
    // if you prefer, you can use PHP constants instead of hardcoded numbers
    return $this->redirectToRoute('homepage', [], Response::HTTP_MOVED_PERMANENTLY);

    // redirect to a route with parameters
    return $this->redirectToRoute('app_lucky_number', ['max' => 10]);

    // redirects to a route and maintains the original query string parameters
    return $this->redirectToRoute('blog_show', $request->query->all());

    // redirects to the current route (e.g. for Post/Redirect/Get pattern):
    return $this->redirectToRoute($request->attributes->get('_route'));

    // redirects externally
    return $this->redirect('http://symfony.ac.cn/doc');
}

危险

redirect() 方法不会以任何方式检查其目标。如果您重定向到最终用户提供的 URL,您的应用程序可能会受到未验证的重定向安全漏洞的攻击。

渲染模板

如果您正在提供 HTML,您将需要渲染一个模板。render() 方法渲染一个模板,并将该内容放入一个 Response 对象中供您使用

1
2
// renders templates/lucky/number.html.twig
return $this->render('lucky/number.html.twig', ['number' => $number]);

模板和 Twig 在 创建和使用模板文章中有更详细的解释。

获取服务

Symfony 打包了很多有用的类和功能,称为 服务。这些用于渲染模板、发送电子邮件、查询数据库以及您可以想到的任何其他“工作”。

如果您需要在控制器中使用服务,请使用其类(或接口)名称类型提示一个参数,Symfony 将自动注入它。这需要您的控制器注册为服务

1
2
3
4
5
6
7
8
9
10
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
// ...

#[Route('/lucky/number/{max}')]
public function number(int $max, LoggerInterface $logger): Response
{
    $logger->info('We are logging!');
    // ...
}

太棒了!

您可以使用类型提示哪些其他服务?要查看它们,请使用 debug:autowiring 控制台命令

1
$ php bin/console debug:autowiring

提示

如果您需要控制参数确切的值,或者需要参数,您可以使用 #[Autowire] 属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// ...
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\HttpFoundation\Response;

class LuckyController extends AbstractController
{
    public function number(
        int $max,

        // inject a specific logger service
        #[Autowire(service: 'monolog.logger.request')]
        LoggerInterface $logger,

        // or inject parameter values
        #[Autowire('%kernel.project_dir%')]
        string $projectDir
    ): Response
    {
        $logger->info('We are logging!');
        // ...
    }
}

您可以在 自动定义服务依赖项(自动装配)中阅读有关此属性的更多信息。

与所有服务一样,您也可以在控制器中使用常规的构造函数注入

有关服务的更多信息,请参阅 服务容器 文章。

生成控制器

为了节省时间,您可以安装 Symfony Maker 并告诉 Symfony 生成一个新的控制器类

1
2
3
4
$ php bin/console make:controller BrandNewController

created: src/Controller/BrandNewController.php
created: templates/brandnew/index.html.twig

如果您想从 Doctrine 实体生成整个 CRUD,请使用

1
2
3
4
5
6
7
8
9
10
$ php bin/console make:crud Product

created: src/Controller/ProductController.php
created: src/Form/ProductType.php
created: templates/product/_delete_form.html.twig
created: templates/product/_form.html.twig
created: templates/product/edit.html.twig
created: templates/product/index.html.twig
created: templates/product/new.html.twig
created: templates/product/show.html.twig

管理错误和 404 页面

当找不到内容时,您应该返回 404 响应。为此,抛出一种特殊的异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

// ...
public function index(): Response
{
    // retrieve the object from database
    $product = ...;
    if (!$product) {
        throw $this->createNotFoundException('The product does not exist');

        // the above is just a shortcut for:
        // throw new NotFoundHttpException('The product does not exist');
    }

    return $this->render(/* ... */);
}

createNotFoundException() 方法只是创建特殊的 NotFoundHttpException 对象的快捷方式,它最终会在 Symfony 内部触发 404 HTTP 响应。

如果您抛出一个异常,该异常扩展或是一个 HttpException 的实例,Symfony 将使用适当的 HTTP 状态代码。否则,响应将具有 500 HTTP 状态代码

1
2
// this exception ultimately generates a 500 status error
throw new \Exception('Something went wrong!');

在任何情况下,都会向最终用户显示错误页面,并向开发人员显示完整的调试错误页面(即当您处于“Debug”模式时 - 请参阅 配置 Symfony)。

要自定义向用户显示的错误页面,请参阅 如何自定义错误页面 文章。

Request 对象作为控制器参数

如果您需要读取查询参数、获取请求头或访问上传的文件怎么办?该信息存储在 Symfony 的 Request 对象中。要在您的控制器中访问它,请将其添加为参数并使用 Request 类对其进行类型提示

1
2
3
4
5
6
7
8
9
10
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
// ...

public function index(Request $request): Response
{
    $page = $request->query->get('page', 1);

    // ...
}

继续阅读以获取有关使用 Request 对象的更多信息。

请求的自动映射

可以使用属性自动将请求的负载和/或查询参数映射到控制器的操作参数。

单独映射查询参数

假设用户向您发送一个带有以下查询字符串的请求:https://example.com/dashboard?firstName=John&lastName=Smith&age=27。感谢 MapQueryParameter 属性,控制器的操作参数可以自动实现

1
2
3
4
5
6
7
8
9
10
11
12
13
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\MapQueryParameter;

// ...

public function dashboard(
    #[MapQueryParameter] string $firstName,
    #[MapQueryParameter] string $lastName,
    #[MapQueryParameter] int $age,
): Response
{
    // ...
}

#[MapQueryParameter] 可以接受一个名为 filter 的可选参数。您可以使用 PHP 中定义的 Validate Filters 常量

1
2
3
4
5
6
7
8
9
10
11
12
13
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\MapQueryParameter;

// ...

public function dashboard(
    #[MapQueryParameter(filter: \FILTER_VALIDATE_REGEXP, options: ['regexp' => '/^\w+$/'])] string $firstName,
    #[MapQueryParameter] string $lastName,
    #[MapQueryParameter(filter: \FILTER_VALIDATE_INT)] int $age,
): Response
{
    // ...
}

映射整个查询字符串

另一种可能性是将整个查询字符串映射到一个对象中,该对象将保存可用的查询参数。假设您声明了以下 DTO 及其可选的验证约束

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
namespace App\Model;

use Symfony\Component\Validator\Constraints as Assert;

class UserDto
{
    public function __construct(
        #[Assert\NotBlank]
        public string $firstName,

        #[Assert\NotBlank]
        public string $lastName,

        #[Assert\GreaterThan(18)]
        public int $age,
    ) {
    }
}

然后,您可以在控制器中使用 MapQueryString 属性

1
2
3
4
5
6
7
8
9
10
11
12
use App\Model\UserDto;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\MapQueryString;

// ...

public function dashboard(
    #[MapQueryString] UserDto $userDto
): Response
{
    // ...
}

您可以自定义映射期间使用的验证组,以及验证失败时要返回的 HTTP 状态

1
2
3
4
5
6
7
8
9
10
11
12
13
use Symfony\Component\HttpFoundation\Response;

// ...

public function dashboard(
    #[MapQueryString(
        validationGroups: ['strict', 'edit'],
        validationFailedStatusCode: Response::HTTP_UNPROCESSABLE_ENTITY
    )] UserDto $userDto
): Response
{
    // ...
}

如果验证失败,则返回的默认状态代码为 404。

即使请求查询字符串为空,如果您也需要有效的 DTO,请为您的控制器参数设置默认值

1
2
3
4
5
6
7
8
9
10
11
12
use App\Model\UserDto;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\MapQueryString;

// ...

public function dashboard(
    #[MapQueryString] UserDto $userDto = new UserDto()
): Response
{
    // ...
}

映射请求负载

在创建 API 并处理除 GET 之外的其他 HTTP 方法(如 POSTPUT)时,用户数据不会存储在查询字符串中,而是直接存储在请求负载中,如下所示

1
2
3
4
5
{
    "firstName": "John",
    "lastName": "Smith",
    "age": 28
}

在这种情况下,也可以通过使用 MapRequestPayload 属性将此负载直接映射到您的 DTO

1
2
3
4
5
6
7
8
9
10
11
12
use App\Model\UserDto;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;

// ...

public function dashboard(
    #[MapRequestPayload] UserDto $userDto
): Response
{
    // ...
}

此属性允许您自定义序列化上下文以及负责在请求和 DTO 之间进行映射的类

1
2
3
4
5
6
7
8
9
10
public function dashboard(
    #[MapRequestPayload(
        serializationContext: ['...'],
        resolver: App\Resolver\UserDtoResolver
    )]
    UserDto $userDto
): Response
{
    // ...
}

您还可以自定义使用的验证组、验证失败时要返回的状态代码以及支持的负载格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use Symfony\Component\HttpFoundation\Response;

// ...

public function dashboard(
    #[MapRequestPayload(
        acceptFormat: 'json',
        validationGroups: ['strict', 'read'],
        validationFailedStatusCode: Response::HTTP_NOT_FOUND
    )] UserDto $userDto
): Response
{
    // ...
}

如果验证失败,则返回的默认状态代码为 422。

提示

如果您构建 JSON API,请确保将您的路由声明为使用 JSON 格式。这将使错误处理在发生验证错误时输出 JSON 响应,而不是 HTML 页面

1
#[Route('/dashboard', name: 'dashboard', format: 'json')]

如果您想映射特定 DTO 的嵌套数组,请确保安装 phpstan/phpdoc-parserphpdocumentor/type-resolver

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public function dashboard(
    #[MapRequestPayload] EmployeesDto $employeesDto
): Response
{
    // ...
}

final class EmployeesDto
{
    /**
     * @param UserDto[] $users
     */
    public function __construct(
        public readonly array $users = []
    ) {}
}

您可以告诉 Symfony 将每个 DTO 对象转换为数组并返回如下内容,而不是返回 DTO 对象数组

1
2
3
4
5
6
7
8
9
10
11
12
[
    {
        "firstName": "John",
        "lastName": "Smith",
        "age": 28
    },
    {
        "firstName": "Jane",
        "lastName": "Doe",
        "age": 30
    }
]

要做到这一点,请将参数映射为一个数组,并使用属性的 type 选项配置每个元素的类型

1
2
3
4
5
6
public function dashboard(
    #[MapRequestPayload(type: UserDto::class)] array $users
): Response
{
    // ...
}

7.1

#[MapRequestPayload]type 选项是在 Symfony 7.1 中引入的。

映射上传的文件

Symfony 提供了一个名为 #[MapUploadedFile] 的属性,用于将一个或多个 UploadedFile 对象映射到控制器参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\MapUploadedFile;
use Symfony\Component\Routing\Attribute\Route;

class UserController extends AbstractController
{
    #[Route('/user/picture', methods: ['PUT'])]
    public function changePicture(
        #[MapUploadedFile] UploadedFile $picture,
    ): Response {
        // ...
    }
}

在本例中,关联的 参数解析器 根据参数名称($picture)获取 UploadedFile。如果未提交文件,则会抛出 HttpException。您可以通过使控制器参数可为空来更改此行为

1
2
#[MapUploadedFile]
?UploadedFile $document

#[MapUploadedFile] 属性还允许传递要应用于上传文件的约束列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\MapUploadedFile;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Validator\Constraints as Assert;

class UserController extends AbstractController
{
    #[Route('/user/picture', methods: ['PUT'])]
    public function changePicture(
        #[MapUploadedFile([
            new Assert\File(mimeTypes: ['image/png', 'image/jpeg']),
            new Assert\Image(maxWidth: 3840, maxHeight: 2160),
        ])]
        UploadedFile $picture,
    ): Response {
        // ...
    }
}

验证约束在将 UploadedFile 注入控制器参数之前进行检查。如果存在约束冲突,则会抛出 HttpException,并且不执行控制器的操作。

如果您需要上传文件集合,请将它们映射到数组或可变参数。给定的约束将应用于所有文件,如果其中任何一个失败,则会抛出 HttpException

1
2
3
4
5
#[MapUploadedFile(new Assert\File(mimeTypes: ['application/pdf']))]
array $documents

#[MapUploadedFile(new Assert\File(mimeTypes: ['application/pdf']))]
UploadedFile ...$documents

使用 name 选项将上传的文件重命名为自定义值

1
2
#[MapUploadedFile(name: 'something-else')]
UploadedFile $document

此外,您可以更改存在约束冲突时抛出的 HTTP 异常的状态代码

1
2
3
4
5
#[MapUploadedFile(
    constraints: new Assert\File(maxSize: '2M'),
    validationFailedStatusCode: Response::HTTP_REQUEST_ENTITY_TOO_LARGE
)]
UploadedFile $document

7.1

#[MapUploadedFile] 属性是在 Symfony 7.1 中引入的。

管理会话

您可以在用户的会话中存储特殊消息,称为“flash”消息。按照设计,flash 消息旨在仅使用一次:当您检索到它们时,它们会自动从会话中消失。此功能使“flash”消息特别适合存储用户通知。

例如,假设您正在处理 表单 提交

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
// ...

public function update(Request $request): Response
{
    // ...

    if ($form->isSubmitted() && $form->isValid()) {
        // do some sort of processing

        $this->addFlash(
            'notice',
            'Your changes were saved!'
        );
        // $this->addFlash() is equivalent to $request->getSession()->getFlashBag()->add()

        return $this->redirectToRoute(/* ... */);
    }

    return $this->render(/* ... */);
}

阅读以获取有关使用会话的更多信息。

Request 和 Response 对象

正如 前面提到的,Symfony 会将 Request 对象传递给任何使用 Request 类进行类型提示的控制器参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

public function index(Request $request): Response
{
    $request->isXmlHttpRequest(); // is it an Ajax request?

    $request->getPreferredLanguage(['en', 'fr']);

    // retrieves GET and POST variables respectively
    $request->query->get('page');
    $request->getPayload()->get('page');

    // retrieves SERVER variables
    $request->server->get('HTTP_HOST');

    // retrieves an instance of UploadedFile identified by foo
    $request->files->get('foo');

    // retrieves a COOKIE value
    $request->cookies->get('PHPSESSID');

    // retrieves an HTTP request header, with normalized, lowercase keys
    $request->headers->get('host');
    $request->headers->get('content-type');
}

Request 类有几个公共属性和方法,它们返回您需要的关于请求的任何信息。

Request 类似,Response 对象也有一个公共的 headers 属性。此对象是 ResponseHeaderBag 类型,并提供了用于获取和设置响应头的方法。header 名称是标准化的。因此,名称 Content-Type 等同于名称 content-typecontent_type

在 Symfony 中,控制器必须返回一个 Response 对象

1
2
3
4
5
6
7
8
use Symfony\Component\HttpFoundation\Response;

// creates a simple Response with a 200 status code (the default)
$response = new Response('Hello '.$name, Response::HTTP_OK);

// creates a CSS-response with a 200 status code
$response = new Response('<style> ... </style>');
$response->headers->set('Content-Type', 'text/css');

为了方便这一点,包含了不同的 response 对象来处理不同的响应类型。下面提到了一些。要了解更多关于 RequestResponse(以及不同的 Response 类)的信息,请参阅 HttpFoundation 组件文档

注意

从技术上讲,控制器可以返回 Response 以外的值。但是,您的应用程序负责将该值转换为 Response 对象。这通过 事件(特别是 kernel.view 事件)处理,这是一个您将在稍后学习的高级功能。

访问配置值

要从控制器获取任何 配置参数 的值,请使用 getParameter() 助手方法

1
2
3
4
5
6
// ...
public function index(): Response
{
    $contentsDir = $this->getParameter('kernel.project_dir').'/contents';
    // ...
}

返回 JSON 响应

要从控制器返回 JSON,请使用 json() 助手方法。这将返回一个 JsonResponse 对象,该对象会自动编码数据

1
2
3
4
5
6
7
8
9
10
11
use Symfony\Component\HttpFoundation\JsonResponse;
// ...

public function index(): JsonResponse
{
    // returns '{"username":"jane.doe"}' and sets the proper Content-Type header
    return $this->json(['username' => 'jane.doe']);

    // the shortcut defines three optional arguments
    // return $this->json($data, $status = 200, $headers = [], $context = []);
}

如果您的应用程序中启用了 serializer 服务,它将用于将数据序列化为 JSON。否则,将使用 json_encode 函数。

流式文件响应

您可以使用 file() 助手从控制器内部提供文件

1
2
3
4
5
6
7
8
use Symfony\Component\HttpFoundation\BinaryFileResponse;
// ...

public function download(): BinaryFileResponse
{
    // send the file contents and force the browser to download it
    return $this->file('/path/to/some_file.pdf');
}

file() 助手提供了一些参数来配置其行为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
// ...

public function download(): BinaryFileResponse
{
    // load the file from the filesystem
    $file = new File('/path/to/some_file.pdf');

    return $this->file($file);

    // rename the downloaded file
    return $this->file($file, 'custom_name.pdf');

    // display the file contents in the browser instead of downloading it
    return $this->file('invoice_3241.pdf', 'my_invoice.pdf', ResponseHeaderBag::DISPOSITION_INLINE);
}

发送早期提示

Early hints 告诉浏览器在应用程序发送响应内容之前就开始下载一些资源。这提高了感知性能,因为浏览器可以预取一旦最终发送完整响应后将需要的资源。这些资源通常是 Javascript 或 CSS 文件,但它们可以是任何类型的资源。

注意

为了工作,您使用的 SAPI 必须支持此功能,例如 FrankenPHP

您可以从控制器操作发送 early hints,这要归功于 sendEarlyHints() 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
namespace App\Controller;

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

class HomepageController extends AbstractController
{
    #[Route("/", name: "homepage")]
    public function index(): Response
    {
        $response = $this->sendEarlyHints([
            new Link(rel: 'preconnect', href: 'https://fonts.google.com'),
            (new Link(href: '/style.css'))->withAttribute('as', 'style'),
            (new Link(href: '/script.js'))->withAttribute('as', 'script'),
        ]);

        // prepare the contents of the response...

        return $this->render('homepage/index.html.twig', response: $response);
    }
}

从技术上讲,Early Hints 是一个信息性的 HTTP 响应,状态代码为 103sendEarlyHints() 方法创建一个状态代码为该代码的 Response 对象,并立即发送其标头。

这样,浏览器可以立即开始下载资源;就像上面示例中的 style.cssscript.js 文件。sendEarlyHints() 方法还返回 Response 对象,您必须使用该对象来创建从控制器操作发送的完整响应。

最后的想法

在 Symfony 中,控制器通常是一个类方法,用于接受请求并返回 Response 对象。当与 URL 映射时,控制器变得可访问,并且可以查看其响应。

为了方便控制器的开发,Symfony 提供了 AbstractController。它可以用于扩展控制器类,从而允许访问一些常用工具,例如 render()redirectToRoute()AbstractController 还提供了 createNotFoundException() 实用程序,该实用程序用于返回未找到页面的响应。

在其他文章中,您将学习如何从控制器内部使用特定服务,这些服务将帮助您持久化和获取数据库中的对象、处理表单提交、处理缓存等等。

继续前进!

接下来,了解所有关于 使用 Twig 渲染模板 的信息。

本作品,包括代码示例,根据 Creative Commons BY-SA 3.0 许可获得许可。
TOC
    版本