配置

3.3 版本
维护中的版本

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

基础相关配置 

Best Practice

Best Practice

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 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.ymlapp/config/config_prod.yml文件,它们能让你覆写针对不同环境的特定的选项值。

常量 v.s. 配置选项 

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

Best Practice

Best Practice

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

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

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

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

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

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
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.

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)