Flex: 组合你的应用
在阅读了本教程的第一部分之后,您已经决定 Symfony 值得再花 10 分钟了解。非常棒的选择!在第二部分中,您将学习 Symfony Flex:这个神奇的工具让添加新功能就像运行一个命令一样简单。这也是 Symfony 成为小型微服务或大型应用的理想选择的原因。好奇吗?太好了!
Symfony: 启动微型应用!
除非您正在构建纯 API(稍后会详细介绍!),否则您可能需要渲染 HTML。为此,您将使用 Twig。Twig 是一个灵活、快速且安全的 PHP 模板引擎。它使您的模板更具可读性和简洁性;它也使它们对网页设计师更加友好。
我们的应用中是否已经安装了 Twig?实际上,还没有!这太棒了!当您启动一个新的 Symfony 项目时,它是小巧的:只有最关键的依赖项包含在您的 composer.json
文件中
1 2 3 4 5 6 7
"require": {
"...",
"symfony/console": "^6.1",
"symfony/flex": "^2.0",
"symfony/framework-bundle": "^6.1",
"symfony/yaml": "^6.1"
}
这使得 Symfony 与任何其他 PHP 框架都不同!Symfony 应用不是从一个臃肿的应用开始,其中包含您可能永远需要的所有可能的功能,而是小巧、简单且快速。您可以完全控制要添加的内容。
Flex Recipes 和别名
那么我们如何安装和配置 Twig 呢?只需运行一个命令
1
$ composer require twig
由于 Symfony Flex,在我们项目的 Composer 插件中,幕后发生了两个非常有趣的事情。
首先,twig
不是 Composer 包的名称:它是一个 Flex 别名,指向 symfony/twig-bundle
。Flex 为 Composer 解析该别名。
其次,Flex 为 symfony/twig-bundle
安装了一个 recipe。什么是 recipe?它是一种库通过添加和修改文件来自动配置自身的方式。借助 recipes,添加功能变得无缝且自动化:安装一个包就完成了!
您可以在 recipes 仓库中的 RECIPES.md 中找到 recipes 和别名的完整列表。
这个 recipe 做了什么?除了在 config/bundles.php
中自动启用该功能外,它还添加了 3 个内容
config/packages/twig.yaml
- 一个配置文件,使用合理的默认值设置 Twig。
config/packages/test/twig.yaml
- 一个配置文件,在运行测试时更改一些 Twig 选项。
templates/
- 这是模板文件将存放的目录。该 recipe 还添加了一个
base.html.twig
布局文件。
Twig: 渲染模板
借助 Flex,只需一个命令,您就可以立即开始使用 Twig
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
<?php
// src/Controller/DefaultController.php
namespace App\Controller;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\HttpFoundation\Response;
+ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
- class DefaultController
+ class DefaultController extends AbstractController
{
#[Route('/hello/{name}', methods: ['GET'])]
public function index(string $name): Response
{
- return new Response("Hello $name!");
+ return $this->render('default/index.html.twig', [
+ 'name' => $name,
+ ]);
}
}
通过扩展 AbstractController
,您现在可以访问许多快捷方法和工具,例如 render()
。创建新模板
1 2
{# templates/default/index.html.twig #}
<h1>Hello {{ name }}</h1>
就是这样!{{ name }}
语法将打印从控制器传入的 name
变量。如果您是 Twig 新手,欢迎!您将在稍后了解更多关于其语法和功能的信息。
但是,现在页面仅包含 h1
标签。为了给它一个 HTML 布局,扩展 base.html.twig
1 2 3 4 5 6
{# templates/default/index.html.twig #}
{% extends 'base.html.twig' %}
{% block body %}
<h1>Hello {{ name }}</h1>
{% endblock %}
这称为模板继承:我们的页面现在从 base.html.twig
继承 HTML 结构。
Profiler: 调试天堂
Symfony 最酷的功能之一甚至尚未安装!让我们修复它
1
$ composer require profiler
是的!这是另一个别名!Flex 还安装了另一个 recipe,它自动化了 Symfony Profiler 的配置。结果是什么?刷新!
看到底部的黑色工具栏了吗?那是 Web 调试工具栏,它是您新的最佳朋友。通过悬停在每个图标上,您可以获得有关执行了哪些控制器、性能信息、缓存命中和未命中以及更多信息。单击任何图标进入 profiler,您可以在其中获得更多详细的调试和性能数据!
哦,当您安装更多库时,您将获得更多工具(例如,显示数据库查询的 Web 调试工具栏图标)。
您现在可以直接使用 profiler,因为它通过 recipe 配置了自身。我们还能安装什么?
丰富的 API 支持
您正在构建 API 吗?您已经可以从任何控制器返回 JSON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
// src/Controller/DefaultController.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;
class DefaultController extends AbstractController
{
// ...
#[Route('/api/hello/{name}', methods: ['GET'])]
public function apiHello(string $name): JsonResponse
{
return $this->json([
'name' => $name,
'symfony' => 'rocks',
]);
}
}
但是为了获得真正丰富的 API,请尝试安装 API Platform
1
$ composer require api
这是 api-platform/api-pack
Symfony pack 的别名,它依赖于其他几个包,例如 Symfony 的 Validator 和 Security 组件,以及 Doctrine ORM。实际上,Flex 安装了 5 个 recipes!
但像往常一样,我们可以立即开始使用新库。想要为 product
表创建一个丰富的 API 吗?创建一个 Product
实体并为其赋予 #[ApiResource]
属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
// src/Entity/Product.php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ApiResource]
class Product
{
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'AUTO')]
#[ORM\Column(type: 'integer')]
private int $id;
#[ORM\Column(type: 'string')]
private string $name;
#[ORM\Column(type: 'integer')]
private int $price;
// ...
}
完成!您现在拥有列出、添加、更新和删除产品的端点!不相信我?运行以下命令列出您的路由
1 2 3 4 5 6 7 8 9 10 11 12
$ php bin/console debug:router
------------------------------ -------- -------------------------------------
Name Method Path
------------------------------ -------- -------------------------------------
api_products_get_collection GET /api/products.{_format}
api_products_post_collection POST /api/products.{_format}
api_products_get_item GET /api/products/{id}.{_format}
api_products_put_item PUT /api/products/{id}.{_format}
api_products_delete_item DELETE /api/products/{id}.{_format}
...
------------------------------ -------- -------------------------------------
更多特性、架构和速度
我希望您和我一样对 Flex 感到兴奋!但我们还有一个章节,而且是最重要的章节。我想向您展示 Symfony 如何使您能够快速构建功能,而不会牺牲代码质量或性能。这一切都与服务容器有关,它是 Symfony 的超级力量。继续阅读:关于 架构。