配置信息通常被细分到程序的不同部分(比如基本信息和安全凭证)和不同的环境(开发环境、生产环境)。这就是为何Symfony推荐你将程序配置分为三部分的原因。

基础相关配置

Best Practice

Best Practice

将基本信息在app/config/parameters.yml文件中进行配置。

默认的parameter.yml文件遵循了这个实践,定义了一些与数据库和邮件服务器等基础信息相关的配置选项:

  1. # app/config/parameters.yml
  2. parameters:
  3. database_driver: pdo_mysql
  4. database_host: 127.0.0.1
  5. database_port: ~
  6. database_name: symfony
  7. database_user: root
  8. database_password: ~
  9. mailer_transport: smtp
  10. mailer_host: 127.0.0.1
  11. mailer_user: ~
  12. mailer_password: ~
  13.  
  14. # ...

这些选项没有被定义在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.ymlapp/config/config_prod.yml文件,它们能让你覆写针对不同环境的特定的选项值。

常量 v.s. 配置选项

一个常见的错误是,在定义程序级别的配置时去新建一个“永远不变”的全新选项,比如分页中所显示的条目数。

Best Practice

Best Practice

对于不经常变化的值使用常量进行配置。

传统的配置方式让很多Symfony程序都有下面这样的选项,通常被用来控制显示条目:

  1. # app/config/config.yml
  2. parameters:
  3. homepage.num_items: 10

如果你已经这样做了,实际上你可能很少 去改变这些值。创建一个配置选项然后从不去改变它,那就是不必要。我们推荐你将这些值定义为常量,比如你可以在Postentity中定义一个NUM_ITEM

  1. // src/AppBundle/Entity/Post.php
  2. namespace AppBundle\Entity;
  3.  
  4. class Post
  5. {
  6. const NUM_ITEMS = 10;
  7.  
  8. // ...
  9. }

这样做的好处是你可以在程序中的任何地方使用这个值。而使用参数时,你只能通过使用容器来访问它们:

常量可以在Twig模板中使用,多亏了constant()方法

  1. <p>
  2. Displaying the {{ constant('NUM_ITEMS', post) }} most recent results.
  3. </p>

而且在Doctrine entity和repository中可以很容易地取到这些值,而很难通过容器来获得:

  1. namespace AppBundle\Repository;
  2.  
  3. use Doctrine\ORM\EntityRepository;
  4. use AppBundle\Entity\Post;
  5.  
  6. class PostRepository extends EntityRepository
  7. {
  8. public function findLatest($limit = Post::NUM_ITEMS)
  9. {
  10. // ...
  11. }
  12. }

使用常量作为配置值的唯一不利点在于,在测试环节中你不能重新定义它们。

语义化配置:禁止使用

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.