Symfony学习笔记 - Symfony最佳业务实践

原书链接
本书是Symfony开发者的推荐的应用开发哲学。

Configuration

1、用.env文件,并为每个环境构建一个.env文件。
2、当有敏感信息的时候,比如API key,你可以将这些敏感信息存在Symfony's secrets management system.
3、对于应用程序参数,在config/services.yaml中,进行定义,你可以根据环境来覆盖这些配置,比如services_dev.yaml或者services_prod.yaml
4、应用程序参数用短和前缀的参数名,比如:
config/services.yaml parameters: # don't do this: 'dir' is too generic, and it doesn't convey any meaning app.dir: '...' # do this: short but easy to understand names app.contents_dir: '...'
5、用常量定义很少改变的选项
`
namespace App\Entity;

class Post
{
public const NUMBER_OF_ITEMS = 10;

// ...

}
`

业务逻辑(Business Controller)

6、不要创建任何Bundle来组织你的应用程序逻辑
如果你要复用一些项目中的特性,创建Bundle,否则,通过namespace来组织你的业务模块。

7、用自动装配(Autowiring)来构造应用程序服务(Service)
服务自动装配(Service autowiring)是一项功能,它通过读取您构造函数(或其他方法)中的类型提示(type-hints),自动将正确的服务传递给每个方法,从而无需显式配置服务,并简化应用程序的维护工作。
将其与服务自动配置(service autoconfiguration)结合使用,还可为需要特定标签的服务(如Twig扩展、事件订阅器等)自动添加相应的服务标签。

8、无论什么时候,Service都必须是私有的
声明Service是private,以避免在外部同get来访问该Service。你应该通过依赖注入(Dependency Injection)的方式来使用Service。

9、用yaml格式来配置你自己的Service
如果你使用默认的yaml文件来配置service,大多数的service可以自动配置。但在一些特殊情况下,你可能需要手工进行配置。
yaml格式是symfony推荐的配置格式,因为他对新来者友好并且精确。

10、用属性(Attributes)来定义Doctrine的实体(Entity)映射
Doctrine Entity是你将存在数据库里面的php 对象。Doctrine通过你配置的属性,来了解你的Entities。
Doctrine支持多种元数据格式,但是属性是迄今为止最方便、快捷的方式,来寻找你的映射信息。

Controller

11、让你的Controller扩展AbstractController
Symfony的AbstractController提供了一些基础的操作,比如展示模板或者安全性检查。Controller中,应该是几行胶水代码(glue-code,是软件工程中一种常见的模式,指那些专注于集成和协调现有组件、而非实现核心功能的代码)。

12、使用属性(Attribute)来配置路由、缓存和安全性
使用属性来配置路由、缓存和安全性,可以简化配置。你不必浏览各种文件,来查找配置。配置应该就存在于你需要的地方,并且只用一种格式来使用它。

13、使用依赖注入(Dependency Injection)来使用服务(Service)
如果你的Controller扩展了AbstractController,那么你就可以通过$this->container->get()来使用服务了。相反,你应该通过方法或者构造器中,参数的类型提示(type-hints),使用注入的方式,来取得服务。

14、使用值解析器(EntityValueResolvers),如果他们便利
如果你正在使用Doctrine,可以使用值解析器,他可以将一个查询参数自动转换成实体对象,并作为参数传递过去。如果找不到,会返回一个404错误。
在Controller中,如果你从一个路由变量中创建实体的方式比这要复杂,他是更好的方式,来做Doctrine查询。
[Route('/api/users/{id}', methods: ['GET'])] public function getUser(User $user): JsonResponse { return $this->json($user); }

模板Template

15、使用snake case的方式,来命名模板名和变量名。

16、对于可复用的模板片段,使用"_"作为前缀

表单(Form)

17、将你的Form定义为php Class
将Form定义为Class,方便你在其他地方可以服用。不要在Controller中创建Form,可以简化和Controller的代码,使其易于维护。

18、在Template中,添加Form按钮
由于CSS和其他属性都在模板里面,在模板中定义Button,将更加方便。
但是,如果你需要定义多个submit buton,那么最好还是Controller中,进行定义,否则,挡处理该Form时,你不知道哪一个Button被点击。

19、在底层的实体对象上,添加约束(Contraint)
​​如果将验证规则(Validation Constraints)直接附加在表单字段(Form Fields)上,而不是在实体类(Mapped Object)上定义,会导致验证逻辑无法被其他表单或场景复用​​。

20、使用同一个action来处理表单的展示和和处理
由于表单的展示和处理基本上是一样的,在Controller中,可以使用同一action来处理他们。

国际化

21、翻译文件,使用XLIFF文件格式
对于翻译者而言,XLIFF和gettext有最好的支持。并且,由于XLIFF是XML的,你可以在编写的时候检查他是否合法。

22、用Key来翻译,而不是基于内容字符串
key的名称需要能描述他的用途,而不是基于他的位置。比如使用label.username,而不是edit_form.label.username

防火墙(Firewall)

23、仅仅使用一个个防火墙
除非你有两套认证系统,比如主站通过表单登录,而token可以登录到api。简单起见,推荐只需要一个Firewall

24、使用自动的密码哈希加密器
自动的密码哈希加密器会根据php的安装,自动选择最好的哈希加密器。目前,最好的是bcrypt。

25、通过 Voter组件实现细粒度的权限控制​​
如果你的安全逻辑很复杂,你应该创建一个定制的安全voter,而不是在安全属性里面,定义个长的表达式。

Web资源

26、使用AssetMapper来管理你的Web资源(包括js、css、图片等)

测试

27、对你的URL进行冒烟测试
软件工程里面,冒烟测试是指“进行初步测试,以发现那些足够严重的简单缺陷,从而足以否决一个潜在的软件发布版本”。利用PHPUnit,你能够定义一个功能测试,来验证所有的应用程序URL成功加载。

28、在功能测试中,硬编码URL
在 Symfony 应用中,建议通过路由生成 URL,以便在 URL 变更时自动更新所有链接。然而,当公共 URL 发生变化时,除非您设置了到新 URL 的重定向,否则用户将无法访问该页面。
因此,在测试中建议使用原始 URL 而非通过路由生成。这样当路由发生变化时,测试会失败,从而提醒您必须设置重定向。

目录名规则

29、src\中,PSR-4自动加载的代码,子目录需要大写(比如Controller),目录名需要与namespace匹配;而不需要自动加载的代码目录或者非PHP代码,首字母小写(比如translations,config)。这样,即遵循了PHP的PSR-4规范,又符合unix系统的文件规范。历史遗留问题(比如vendors)除外。
30、对于含有namespace的目录,用单数(比如Controller),不含有namespace的目录,可以根据unix文件系统的规则,用复数(比如tanslations)。
31、对于Controller中的路由名称,推荐使用snake case风格,以与Symfony和代码自动生成器的规则保持一致

posted @ 2025-09-10 22:06  繁星灼灼  阅读(5)  评论(0)    收藏  举报