Symfony最佳实践(官方推荐)
几天前,Fabien Potencier 通过 Sensio 发布了一本电子书,其中汇集了开发 Symfony 项目的最佳实践和建议。 根据社区发布的建议编制,本文档的目的是提供一组与 ph 相关的建议ilo来自 Symfony 的索菲亚。 我将尝试简要总结这篇文章中用英语描述的 31 个技巧。
介绍
本文档以一些建议和几句话开头,旨在通过文档启发我们。
“本文档不是教程”
本文档旨在供所有 Symfony 开发人员阅读。 既是专家又是新手。
“不要重构你的应用程序”
从文档的开头,就特别说明了在阅读本文之后,我们不应该更新和重构我们的应用程序,以使其完全符合 Sensio 的多项建议。 因此,我们可以立即将文档中提出的第一个想法联系起来:这些良好实践应该让我们简化生活,并简化代码审查。 为了支持我的观点,提出三个理由:
- 您现有的应用程序并没有错,它们只是遵循了另一套准则;
- 完整的代码库重构很容易在您的应用程序中引入错误;
- 花在这上面的工作量可以更好地用于改进您的测试或添加为最终用户提供真正价值的功能。
建立专案
在处理如何声明和创建 Symfony 项目的第 2 章中,给出了第一个“最佳实践”:
_始终使用作曲家。 _Composer 通过其依赖项解析介绍了现代 PHP 的基础知识。 多亏了他,文件中注册的依赖项 composer.json 将在您的项目中得到解决和遣返,以便它可用。 此外,可以进行简单的更新。
这样,您就可以尊重 Symfony 项目的结构组织。 (见第 8 页)。
例如:
- 应用程序/缓存 将存储缓存;
- 应用程序/日志 存储日志;
- 应用程序/资源 将为您的应用程序存储模板和全局翻译;
- src / 存储您的应用程序包;
- 供应商/ 存储项目的依赖项;
- 网络/ 将存储资产(css、js、图像等)以及前端文件(app.php),允许您随后将您的请求重定向到您的控制器。
因此,关于捆绑包的新建议。 没有做我自己的分析,这可能会质疑 philo来自 Symfony 的 sophie(我不想要),这里是推荐:
为应用程序创建单个 AppBundle 包。 这是由于 Symfony 的设计方式。 每个包都必须是独立的。 _他们因此应该能够自主和独立地生活。
我让你思考这个建议......
配置
第三章给出了配置其应用程序的建议。 一些配置项可能因开发系统和生产系统而异。
正如建议所示,您必须因此 在文件 app/config/parameters.yml 中定义与您的基础架构相关的配置.
相反,特定于您的项目的配置将是静态的,将在 应用程序/配置/config.yml.
此外,文件 参数.yml 不应该版本化。 这是文件 参数.yml.dist 应该是谁。 该文件将为您提供配置应用程序的基本选项。 (建议第 12 页)。
结果,文件_应用程序/配置/config.yml _本身作为推荐。
在 app/config/config.yml 中设置与您的应用程序相关的配置
但是,按照此建议,建议生成一个文件 配置文件, 配置文件.yml 和一个文件 配置文件.yml. 这些文件旨在存储特定于开发环境和生产环境的常量。
当一个值变化很小时,我们必须将其视为常数。
依赖注入
我们到了 ! 在第三章中,详细介绍了依赖项的使用建议。 如果您觉得我的解释含糊不清,我建议您阅读此建议。
此建议是关于将服务注入服务。 Sensio 建议在文件中声明它们 src/AppBundle/Resources/config/services.yml.
我还邀请您阅读我关于依赖注入以及如何限制超级服务容器使用的文章。
声明内部逻辑
第 4 章介绍如何组织您的应用程序。 根据您的需要,组织会有所不同。 对于全局和非业务功能,Sensio 建议将它们放在一个文件夹中 实用程序 或者干脆把它们从你的包里拿出来,放在一个单独的文件夹里。 在此之后,强烈建议您将类声明为服务。 给出了一个新的建议来帮助我们声明它们。
您的服务名称应尽可能短,最好是一个单词。
选择文件格式
特别关注 Symfony 中的 Yaml 格式,我想这一点会引起不和。 Sensio 毫不妥协地建议在应用程序中使用 Yaml 格式。 开发的包在两种格式之间共享:XML 和 Yaml。
Sensio 决定推荐后者只是因为它更“ 用户友好 ”。 使用另一种格式不会改变您的应用程序的工作方式。
不要为您的服务声明定义变量
这是一种您会在某些捆绑包中看到很多的做法,但 Sensio 会警告您。 这是中给出的示例 食谱 :
1
2
3
4
5
6
7
8
|
#app/config/services.yml
# 服务 defi以类命名空间作为参数的 nition
参数:
slugger.class:AppBundleUtilsSlugger
服务:
重击手:
类:
“%slugger.class%”
|
这是无用代码的示例。 声明用于服务的类是错误的,因为这个变量可能会在代码的其他地方使用。 此外,这也是 Sensio 给出的原因,它降低了服务的创建。
ORM的选择
Sensio 推荐在 Symfony 中使用 Doctrine ORM。 作为一个 Doctrine 用户,它与 Symfony 的集成是非常先进的。 这导致了重新启动我们项目的逻辑组织的建议。 实体声明必须将逻辑保存在一个包中。 请参见第 18 页的示例。
映射声明
Doctrine 映射的声明最好使用在 Doctrine 框架内推荐的注释来执行,但也适用于其他应用程序。
使用注解声明实体映射。
第 19 页给出了一个示例。
安装固定装置
Sensio 没有提出建议,而是建议设置固定装置。 对于外行来说,这些是默认情况下将用于在将应用程序投入生产之前启动应用程序的数据集。
编码标准(第 4 章结尾)
奇怪的是,这部分 Sensio 几乎黯然失色。 我说得很奇怪,因为它对我来说很重要。
Symfony 的编码遵循 PSR1 和 PSR2 标准。 这些标准必须在 Symfony 开发人员社区内推广,但也必须与 PHP 开发人员一起推广。 Symfony 发了一篇文章来收集和突出“ 编码标准 ”。 Sensio 的领导者 Fabien Potencier 还在 GitHub 上放置了一个工具来检查是否符合标准。
Contrôleurs
说到控制器,Symfony 的 philo苏菲“瘦控制器和胖模型”。 这意味着控制器应该保持轻量级。 通过路由访问的每个方法(动作)代表一个动作。 这些方法中的每一个的代码都必须是“轻量级的”并且调用和协调动作。 这些共享必须在服务中。
该模型将控制器呈现为使用应用程序代码/部件。
控制器必须遵循一些规则
- 控制器最多必须有 5 个变量。
- 一个控制器最多有 10 个动作。
- 每个操作最多必须包含 20 行。
- 一个方法可以包含超过 20 行,前提是使用的代码不能分解。
控制器应继承 Sensio 的 FrameworkBundle 基础控制器,并使用注解来管理路由、缓存和安全性。
建议使用注释,但使用 XML、YAML 或 PHP 也是有效的。 应用程序应该只使用一种格式。
- 一个方法可以包含超过 20 行,前提是使用的代码不能分解。
不要使用@Template
这是针对不太意外的建议,但解释特别有力。
不要使用@Template() 注解来配置控制器使用的模板
解释很简单,@Template 使用了一个 TemplateListener,它在事件发生时被调用 内核视图 被抛出。
在本文件的制作过程中,进行了一项测试。 使用@Template 在启动生成之前需要 26 毫秒,而对于使用“ $this->render(…) »,等待时间为 5 毫秒。
使用 ParamConverter 注解
使用此注释可以使实体的水合作用自动化。
使用 ParamConverter 技巧在简单方便的情况下是很好的。
模板
第 6 章详细介绍了模板生成。 在几项建议之后,文档为我们提供的内容没有_fuss _。
- 使用 Twig 模板引擎
Sensio 出于多种原因推荐 Twig。 除了是一个 发动机 被 PHP 社区广泛使用,包括 PHP 开发人员 从头开始,仅由 Symfony 开发人员和其他框架提供。 强调简单,并且清晰可见其产品的促销。 最后,Sensio 保证支持 Symfony 直到它的第 3 版。您还可以找到要进行的第一个转换,以准备您的代码迁移到第 3 版。 - 将应用程序模板存储在 应用程序/资源/视图.
默认情况下,开发人员已经习惯将他们的模板存储在文件夹中 资源库 每捆。 这不是一件坏事,但 Fabien Potencier 建议将应用程序的全局模板存储在上述文件夹中。 - 在中定义你的 Twig 扩展 AppBundle/Twig 和 配置服务 应用程序/配置/服务.yml.
Twig extensions 的能见度很低。 这些扩展虽然非常有用,但有时使用起来过于系统化。 Sensio 展示了我认为必不可少的这一部分,作为将业务代码注入其模板的一种方式。 我建议您阅读如何声明 Twig 扩展。
表格
第 7 章为我们提供了使用表格的说明。
- 在 PHP 类中定义表单。
Symfony 提供了生成 PHP 类的可能性,允许为给定实体自动生成表单。 这 表格 正如他们所说,提供完整的集成。 辅助修改实体。 此外,使用 Forms 可以从模板中移除表单的管理。 - 不要声明一个按钮来发送它的表单。
这是一个令人惊讶的点,因为这个特性是在 Symfony 2.5 中引入的。 在撰写本文时,Symfony 2.6 正在接受过程中,因此尚未正式发布。 因此我们可以对这个功能的有用性提出一些问题,它不应该被使用!在模板中而不是在表单中添加按钮,为什么?
Sensio 团队在其解释中解释说,尽管此功能仍然存在 “方便使用的” 并且它简化了表单的实施,某些功能仍然受到限制。
例如,如果您添加一个类型的按钮 提交 带有“创建”标签的表单不能在编辑页面中重复使用。 然后,您必须将您的表单声明为执行继承的服务,下面不建议这样做。 - 不要使用 Twig 函数 形式() 和_form开始().
专门用于模板渲染的部分已经建立。 她教我们使用 Twig 函数 形式() 和 _ 表单开始()_ 已弃用。 再一次,这对我来说是一个错误,因为这些功能最近才可用。
在 Symfony 中,有几种方法来渲染表单。 在不同的渲染方式中,最好的方式是提供最大灵活性的方式。
使用上面列出的 Twig 函数几乎没有什么好处。 Sensio 谈到了使用原生 HTML 标签时可读性的提高。 尽管有这种说法,但这代表了一个小小的好处……非常小!
将您的表单声明为服务
表单是 PHP 类,这意味着它们可以声明为服务。 您将能够在捆绑包中看到此方法 交响乐之友. 除了我在下面引用的某些情况外,Sensio 不推荐此方法:
- 如果你想重用现有的表格。 在两个表单之间设置继承可以限制所有属性的重写。
- 如果我们想嵌入实体集合。
在添加或编辑表单的情况下,不建议将表单用作服务,因为使用服务会加载 @容器. 此外,很难理解该服务是由控制器使用的。
附加(活页夹)其形式
最近,Sensio 开始不断地将 Symfony2 代码迁移到未来的 Symfony3 代码。 在可以进行的修改列表中(您可以在 UPGRADE-3.md 中找到它们),是新的解决方案 粘结剂 通过表单发送的请求 申请 这是创建的。 新方法详见第 21 页 最佳实践.
语音提取呈现:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
国家 功能 新动作(请求$请求)
{
// 构建你的表单
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $这->容器->获取(“doctrine.orm.default_entity_manager”);
$em->坚持($post);
$em->flush();
回报 $这->重定向($这->生成网址(“admin_post_show”), 排列(“ID” => $post->getId()));
}
}
|
国际化
国际化模块的目的是根据地区或用户的语言将内容从一种语言翻译成另一种语言。 不仅仅是推荐数据,本章的编写更多是为了展示这部分始终保持敏感的可能性。
在第 8 章中,编者详细介绍了如何激活 翻译.
格式怎么样
Symfony 提供多种翻译格式:
- PHP
- Qt
- .po
- 的.mo
- JSON
- CSV
- INI
- 还有很多其他
为您的翻译文件使用 XLIFF 格式。
这句话显然是 Sensio 的推荐。 是的,但是为什么 ? 给了我们一个简短而准确的答案。
在所有支持的格式中,专业翻译工具只支持XLIFF格式和gettext格式。 由于 XLIFF 基于 XML,它受益于内容验证。
Symfony 2.6 带来了一项新功能,允许您在 XLIFF 文件中“评论”(添加注释)。 这是一个很大的创新,因为翻译文件的生成可能会导致翻译人员理解句子的含义或使用它的上下文时出现问题。 总之,XLIFF不错!
在哪里存储我们的翻译文件?
这个问题介绍了一个 最佳实践. Sensio 建议将我们的文件存储在 应用程序/资源/翻译.
通常,我们过去常常将翻译存储在每个包中。 这不是一件坏事,但翻译通常被认为是我们应用程序的全局部分,就像全局模板一样,这就是为什么 Sensio 建议我们将它们存储在 应用.
如何翻译我们的应用程序?
始终使用按键来翻译您的内容。
所以 最棒的, 我不会发表我的意见,因为我几乎没有机会翻译应用程序。 Sensio 建议,要翻译像“用户名”这样的词,您应该使用诸如 标签.用户名.
第 35 页给出了一个例子。
安全
本书的第 9 章涉及 Symfony 的核心部分; 安全 !
Symfony 旨在轻松配置和验证想要连接到我们的应用程序的用户。 这部分非常复杂,充满了细节,所以它是一个粗略的轮廓。 您可以在专用页面上找到更多文档。
声明你的防火墙
配置选项将在文件中输入 安全.yml 这是在 应用程序/配置.
除非你有两个不同的连接到你的应用程序(系统和用户),我们建议只使用一个激活匿名选项的入口防火墙。
哇哇哇! 等等,我到了 Symfony,我什么都不懂!
什么是防火墙?
您可以在 Wanadev 中找到一篇关于如何在 Symfony 上声明和设置本机身份验证的文章。 在这篇文章中,详细介绍了什么是防火墙。
一个防火墙? 为什么 ?
如果您刚刚阅读了上面链接的文章,您可能已经注意到已经声明了几个防火墙。
在给定的文章中,这三个名字是 开发, 主 et 登录. 尽管如此,给定的规则得到遵守,只有防火墙可以被视为网关。
- 开发 : 这个防火墙允许 调试栏 显示。
- 主 : 这个防火墙是我们的 入口点. 匿名用户将能够像遵守规则一样登录。 所有以 / 开头的路由都将使用此条目。
- 登录 : 这是一个防火墙。 这将是我们在单一情况下的网关:如果我们想要连接。 这对于访问登录表单至关重要。
因此,该规则受到尊重。
定义编码
编码密码是一个关键决定。 存在多种算法,例如 沙 (sha1, sha256, sha512, md5...)。
在声明编码时(参见如何声明编码),可以给出三个参数。
- 加密算法(默认:sha512);
- 迭代次数(默认:5000);
- 编码是编码密码的 base64(默认值:true)。
尽管有这些默认值,我还是邀请您修改它们以适合您的应用程序。 Sensio 还推荐使用该算法 bcrypt.使用 bcrypt 编码对用户密码进行加密。
Sensio 解释了如何使用 bcrypt。 这包括一个 盐 价值。 这限制了攻击并且更能抵抗暴力类型的攻击。 您可以在上面的维基百科文章中找到更多详细信息。
设置权限
在连接期间,Symfony 检测应该使用哪个防火墙。 随后,甚至在访问控制器之前,执行访问检查。 它们在文件中定义 安全.yml,
森西奥建议:
- 保护我们的“边缘 URL 模式”,了解我们的全局模式(例如:/admin);
- 使用注解 @安全 越多越好 ;
- 通过服务检查用户的权限 安全上下文 (自 Symfony 2.6 以来,该服务已经发展,请参见此处);
- 定义选民以轻松管理道路安全;
- 使用 ACL 管理对象和用户权限。
使用@Security 注解
Sensio 建议使用@Security 注解。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
使用 SENSIO种子套餐框架ExtraBundle配置路线;
使用 SENSIO种子套餐框架ExtraBundle配置严格安保;
// ...
/ **
* 显示一个表单来创建一个新的 Post 实体。
* @路线(“/new”, name=”admin_post_new”)
* @安全("has_role('ROLE_ADMIN')")
*/
国家 功能 新动作()
{
// ...
}
|
使用表达式使限制更复杂
Sensio 向我们解释说,这个注释还可以生成更复杂的条件,例如两个对象之间的两个属性的比较。 此注释可能需要使用 参数转换器。
您可以在文档中找到更多信息:
- 生成表达式
- 将属性转换为对象
Twig 中的访问安全性
如果你想比较连接的用户和对象的用户,你可以从 Twig 访问 用户 进行中。
1
2
3
|
{% if 应用程序.用户...%}
...
{% ENDIF %}
|
轻松管理您的安全
管理安全性通常是一个敏感的部分,组织我们的代码是成功保护我们的应用程序的重要部分。 指某东西的用途 选民 强烈推荐。 可以考虑其他组织代码的方法。 例如,我们可以将决定转移到实体的方法中。
您可以在第 40 页查看 Sensio 示例。
与 Symfony 提供的可能性相比,这部分细节很少。 如果您面临安全任务,我建议您阅读更多关于这部分的文档。网络资产
资产使我们能够管理 Javascript、CSS、fos 字体、图像等资源,以便可以从您的页面访问它们。
您的资产必须存储在 web/ 文件夹中
这样您就可以像这样将资源加载到模板中:
1
2
|
<链接 REL=“样式表” HREF=« {{ asset(‘css/bootstrap.min.css’) }}« />
<脚本 SRC=« {{ asset(‘js/jquery.min.js’) }}« ></脚本>
|
保留公共 Web 文件夹和其中存储的所有内容。
使用资产
Assetic 有多种兴趣,例如文件编译。 例如,Less、Sass、TypeScript 文件……因此,文件夹 卷筒纸 不能包含 files 等文件 。较少的.
除非您使用 GruntJS,否则请使用 Assetic 来编译、组合和缩小您的资产。
了解有关资产的更多信息
Assetic 是一个完整的工具,尽管有一些缺点。 您可以使用以下链接找到有关此模块的文档:
- 使用资产
- 缩小 CSS 和 JS
- 压缩影像
- 看官方文档
设置测试
大多数开发人员都认为测试是必不可少的。 然而,只有少数人实施了它们。
我们将了解 Sensio 如何建议我们进行测试。
执行单元测试
单元测试用于执行功能测试,而功能测试又会测试应用程序的逻辑。 Symfony 尚未确定任何特定工具来测试您的测试。 工具 单位 et Php规范 被引用。
执行功能测试
为您的功能测试创建良好的场景是必不可少的,但开发人员在实施它们时很快就会遇到问题。
定义功能测试以测试您的页面是否已正确加载。
尝试使用硬编码 URL 而不是通过生成器生成它们。
测试 JavaScript 功能
存在许多工具,例如 貂 (一个 PHPUnit 库)和 卡斯珀JS.
生成数据集
这通常是开发人员关心的问题,生成数据集。
Sensio 推荐使用库 骗子 et 爱丽丝.
结论
本文摘自 最佳实践 为 Symfony的. 虽然保持简单,但本文旨在剖析 50 页的建议,以指导新的 Symfony 开发人员。