配置信息通常被细分到程序的不同部分(比如基本信息和安全凭证)和不同的环境(开发环境、生产环境)。这就是为何Symfony推荐你将程序配置分为三部分的原因。
基础相关配置
Best Practice
Best Practice
将基本信息在app/config/parameters.yml
文件中进行配置。
默认的parameter.yml
文件遵循了这个实践,定义了一些与数据库和邮件服务器等基础信息相关的配置选项:
- # app/config/parameters.yml
- parameters:
- database_driver: pdo_mysql
- database_host: 127.0.0.1
- database_port: ~
- database_name: symfony
- database_user: root
- database_password: ~
- mailer_transport: smtp
- mailer_host: 127.0.0.1
- mailer_user: ~
- mailer_password: ~
- # ...
这些选项没有被定义在app/config/config.yml
中是因为它们并不与程序行为相关。换言之,一旦配置正确,你的程序并不在意你的数据库或是访问数据库时的密钥所在的位置。
正式参数(Canonical Parameters)
Best Practice
Best Practice
将你的程序级别参数app/config/parameters.yml.dist
文件中进行配置。
Symfony自带了一个配置文件名为parameters.yml.dist
,它用来存储程序级的正式参数列表。
当一个新的配置参数被定义给程序时,你应该把它也添加到这个文件中,同时提交到版本控制系统。然后,不管开发者如何更新项目或是将其部署到服务器,Symfony都会检查这个parameter.yml.dist
文件和你本地的parameter.yml
文件之间是否有不同之处。如果有不同,Symfony会要求你提供一个新参数的值,然后把它添加到本地parameter.yml
中。
程序级别的配置
Best Practice
Best Practice
将与程序行为相关的配置选项在app/config/config.yml
文件中进行配置。
config.yml
中的选项被用于调整程序行为,比如邮件发送,或是开启/关闭程序功能(feature toggles)。将这些配置值定义在parameters.yml
是不必要的,因为这将增加一个额外的配置层,而你并不需要在不同的服务器上去改变这些配置的值。
config.yml
文件中的选项在不同的环境中会有很大的不同。这也能解释为什么Symfony还自带了app/config/config_dev.yml
和app/config/config_prod.yml
文件,它们能让你覆写针对不同环境的特定的选项值。
常量 v.s. 配置选项
一个常见的错误是,在定义程序级别的配置时去新建一个“永远不变”的全新选项,比如分页中所显示的条目数。
Best Practice
Best Practice
对于不经常变化的值使用常量进行配置。
传统的配置方式让很多Symfony程序都有下面这样的选项,通常被用来控制显示条目:
- # app/config/config.yml
- parameters:
- homepage.num_items: 10
如果你已经这样做了,实际上你可能很少 去改变这些值。创建一个配置选项然后从不去改变它,那就是不必要。我们推荐你将这些值定义为常量,比如你可以在Post
entity中定义一个NUM_ITEM
:
- // src/AppBundle/Entity/Post.php
- namespace AppBundle\Entity;
- class Post
- {
- const NUM_ITEMS = 10;
- // ...
- }
这样做的好处是你可以在程序中的任何地方使用这个值。而使用参数时,你只能通过使用容器来访问它们:
常量可以在Twig模板中使用,多亏了constant()方法
- <p>
- Displaying the {{ constant('NUM_ITEMS', post) }} most recent results.
- </p>
而且在Doctrine entity和repository中可以很容易地取到这些值,而很难通过容器来获得:
- namespace AppBundle\Repository;
- use Doctrine\ORM\EntityRepository;
- use AppBundle\Entity\Post;
- class PostRepository extends EntityRepository
- {
- public function findLatest($limit = Post::NUM_ITEMS)
- {
- // ...
- }
- }
使用常量作为配置值的唯一不利点在于,在测试环节中你不能重新定义它们。
语义化配置:禁止使用
Best Practice
Best Practice
不要为你的bundles去定义一个语义化的依赖注入(dependency injection)配置。
如同在如何在bundle中加载服务配置中所解释的那样,Symfony bundles在处理配置文件时有两种选择:利用services.yml
文件的常规服务配置,和通过特殊的*Extension
类进行的语义化配置。
尽管语义化配置极其强大,而且提供了“配置验证”等重量级功能,但对于不想作为“第三方bundles”进行分发的bundle来说,那部分与“定义语义化配置”相关的工作量之大之难,明显是得不偿失的。
将敏感配置项全部移出Symfony
当定义敏感配置选项时,比如数据库凭据这些,我们也推荐你将其存储在Symfony项目之外,并令其能够通过环境变量来读取。关于如何实现,请参阅如何在服务容器中设置外部参数。
3.2版新增:Symfony 3.2中增加了通过 %env(…)% 语法支持实时环境变量。3.2之前,你需要使用特殊的 SYMFONY__ variables.