418 12
发新话题
打印

配置symfony

配置层叠 Configuration Cascade

同样的配置信息可以在不同的地方定义多次。例如,你想把你的程序的所有页面的mime-type定义成text/html,只有一个rss模块例外,这个模块需要text/xml的mime-type。symfony可以让你在myapp/config/view.yml里面写第一个定义,然后再myapp/modules/rss/config/view.yml里面写第二个定义。配置系统了解模块级别的定义一定要覆盖应用程序级的定义。

实际上,symfony的配置信息分成好几级:
粒度级别:
框架里的默认配置
整个项目的全局配置 (在 myproject/config/ 里)
项目中应用程序的配置 (在 myproject/apps/myapp/config/ 里)
模块的配置 (在 myproject/apps/myapp/modules/mymodule/config/ 里)
环境级别:
针对某一个环境
所有环境

所有可以自定的属性里,有一些是与环境有关的。因此,很多YAML配置文件是按照环境分成了好几段,最后一段针对所有环境。因此一个典型的symfony配置文件类似于例 5-12。

例 5-12 - symfony配置文件的结构
# 生产环境设置
prod:
  ...

# 开发环境设置
dev:
  ...

# 测试环境设置
test:
  ...

# 自定义环境设置
myenv:
  ...

# 所有环境的设置
all:
  ...

另外,symfony框架本身定义的默认值并不在项目的目录里,它们在你的symfony的$sf_syfmony_data_dir/config/目录里。默认的配置信息在例5-13里的文件里设置。所有的应用程序都会继承到这些设定。

例 5-13 - 默认配置信息, 在 $sf_symfony_data_dir/config/settings.yml里
# Default settings:
default:
   default_module:         default
   default_action:         index
   ...

这些配置会在项目,应用程序,模块的配置信息里面以注释的形式反复出现,如例5-14所示,这样你就可以知道这些默认值并且可以修改它们。

例 5-14 - 默认配置信息, 在 myapp/config/settings.yml 中出现以供参考
#all:
#  default_module:         default
#  default_action:         index
...

这意味着一个属性可以多次定义,最后的取值取决于层叠的结构。任何特定一个环境里定义的参数优先于所有环境里定义的参数,所有环境里的参数优先于默认配置。模块配置里的参数优先于应用程序级里定义的同样参数,应用程序里的参数优先于项目级。这可以通过下面的优先级列表来表示:
模块
应用程序
项目
特定的环境
所有环境
默认

TOP

配置缓存 The Configuration Cache

执行时解析YAML还有处理配置文件的层叠结构会增加每次请求的负担。symfony内建了配置文件缓存机制来提高请求速度。

不管什么格式的配置文件都需要一些特别的类来处理,又叫处理者,这些配置文件被转换成快速的PHP代码。开发环境里,处理着每次请求都会去检查配置文件的变化,这样提高交互性。它们解析改变的文件使你能马上看到YAML改编的效果。但是在生产环境,这样的处理只在第一次请求时进行,处理得到的PHP代码被保存下来给后面的请求使用。这样能提高性能,因为生产环境里的每次请求只需要执行一些优化过的PHP代码。

例如,如果app.yml文件内容如下:
all:                   # 所有环境的设置
  mail:
    webmaster:         webmaster@example.com

那么cache/目录下的config_app.yml.php文件,将包括下面的内容:
[php]
<?php

sfConfig::add(array(
  'app_mail_webmaster' => 'webmaster@example.com',
));

这样,大多数时候,symfony不需要去解析YAML文件,只需要执行cache里的配置信息就可以了。不过在开发环境,symfony会自动比较YAML文件还有配置缓存的修改时间,只重新处理上次请求后修改过的配置文件。

这是symfony与其他很多PHP框架相比的很大的有点,这些PHP框架里每次请求时都会去处理配置文件,即使是生产环境。与Java不同,PHP不会在请求之间共享执行状态。 其他依赖XML配置文件的框架在每次请求时处理XML性能损失很大。symfony不存在这个问题,配置文件带来的速度影响很小。

这样的机制带来一个重要的问题,如果你改变了生产环境的配置信息,你需要强制重新解析所有你修改过的配置文件,这样改变才能生效。你只需要清除缓存就可以了,可以直接清空cache/目录的内容,或是执行clear-cache这个symfony任务:
> symfony clear-cache
从代码里访问配置信息 Accessing the Configuration from Code

所有的配置文件最终都被转换成PHP代码,框架会自动使用很多设置。不过,有时你需要在你的代码中(动作,模版,自定义类等)访问配置文件里定义的设置。settings.yml、apps.yml、module.yml、logging.yml还有i18n.yml里的配置信息可以通过一个特殊的sfConfig类来访问。

TOP

sfConfig类 The sfConfig Class

你可以在程序代码里通过sfConfig类访问配置信息。它是一个配置信息的登记处,它有一些简单的存取方法,这些存取方法可以在程序的任何地方使用。
[php]
// 取得一个设定
parameter = sfConfig::get('param_name', $default_value);

注意你也可以在PHP代码里定义或者覆盖一个设置:
[php]
// 定义一个设定
sfConfig::set('param_name', $value);

参数的名字由几部分组成,中间用下划线分割,顺序如下:
与配置文件名有关的前缀 (sf_ 代表 settings.yml, app_ 代表 app.yml, mod_ 代表 module.yml, sf_i18n_ 代表 i18n.yml, sf_logging_ 代表 logging.yml)
父键名 (如果有), 小写形式
键名, 小写形式

参数名字不包括环境名称,因为PHP代码只能访问到执行时所在的环境里定义的参数。

例如,如果你需要访问app.yml里定义的值,见例5-15,你需要例5-16中的代码。

例 5-15 - app.yml 配置文件样本
all:
  version:        1.5
  .general:
    tax:          19.6
  default_user:
    name:         John Doe
  mail:
    webmaster:    webmaster@example.com
    contact:      contact@example.com
dev:
  mail:
    webmaster:    dummy@example.com
    contact:      dummy@example.com

例 5-16 - 在dev环境从PHP代码里访问配置信息
[php]
echo sfConfig::get('app_version');
=> '1.5'
echo sfConfig::get('app_tax');   // 请注意分类的头会被忽略掉
=> '19.6'
echo sfConfig::get('app_default_user_name);
=> 'John Doe'
echo sfConfig::get('app_mail_webmaster');
=> 'dummy@example.com'
echo sfConfig::get('app_mail_contact');
=> 'dummy@example.com'

所以symfony的配置信息有所有PHP常量的优点,但是没有PHP常量的缺点,因为symfony配置的值可以改变。

所以, 用来给应用程序设定框架设置的settings.yml文件,相当于一系列的sfConfig::set()调用。例 5-17 会被解释为 例 5-18。

例 5-17 - 不完整的settings.yml
all:
  .settings:
    available:              on
    path_info_array:        SERVER
    path_info_key:          PATH_INFO
    url_format:             PATH

例 5-18 - symfony处理settings.yml文件的结果
[php]
sfConfig::add(array(
  'sf_available' => true,
  'sf_path_info_array' => 'SERVER',
  'sf_path_info_key' => 'PATH_INFO',
  'sf_url_format' => 'PATH',
));

settings.yml文件里面设置的含义请参考第19章。

TOP

自定义应用程序配置与app.yml Custom Application Settings and app.yml

大部分与程序功能有关的设置存放在app.yml文件里,这个文件在myproject/apps/myapp/config/目录。app.yml与环境有关,默认是空的。把所有你需要很容易修改的设置放在这个文件里,在代码里用sfConfig类访问它们。如例5-19。

例 5-19 - 这个app.yml给指定的网站定义接受的信用卡类型
all:
  creditcards:
    fake:             off
    visa:             on
    americanexpress:  on

dev:
  creditcards:
    fake:             on

想要知道前环境是否接受fake信用卡,需要这么写代码:
[php]
sfConfig::get('app_creditcards_fake');

TIP 当你要定义一个常量或者一个设置的时候,考虑一下把它放在app.yml里面会不会更好。在这里存放应用程序配置很方便。

如果你的自定义参数用app.yml的语法难以处理,你可以考虑自己定义一套语法。这样你可以把配置信息存在一个新的文件里,用新的处理者解析配置文件。配置文件处理者的资料详见第19章。
更好的使用配置文件的技巧 Tips for Getting More from Configuration Files

在开始写你自己的YAML文件之前,有一些最后的技巧需要掌握。这些技巧可以避免配置信息的重复还有处理你自己的YAML格式。

TOP

在YAML文件里使用常量 Using Constants in YAML Configuration Files

一些配置设定的值取决于其他的设定。为了避免重复设置同样的值,symfony支持在YAML文件里使用常量。如果遇到%包起来的大写形式的设定名(可以通过sfConfig::get()取得值),配置文件处理者会用这个设定的当前值来替换这个常量。见例5-20。

例 5-20 - 在YAML文件里使用常量,以autoload.yml为例
autoload:
  symfony:
    name:           symfony
    path:           %SF_SYMFONY_LIB_DIR%
    recursive:      on
    exclude:        [vendor]

path参数的值会是执行sfConfig::get('sf_symfony_lib_dir')的结果。如果一个配置文件依赖于另一个配置文件,被依赖的配置文件必须先被解析(请查看symfony的源代码来了解配置文件载入的顺序)。app.yml是最后被解析的文件之一,所以你可以在这个文件里使用其它文件里定义的设定。

TOP

在配置文件里使用脚本 Using Scriptable Configuration

有可能你的配置信息与外部参数有关(例如数据库或者其他配置文件)。为了解决这种问题,symfony在把配置文件传给YAML处理者之前先用PHP来解析配置文件。这意味着你可以在YAML文件里使用PHP代码,如例5-21。

例 5-21 - YAML文件可以包含PHP


all:
  translation:
    format:  <?php echo sfConfig::get('sf_i18n') == true ? 'xliff' : 'none' ?>

但是请注意配置文件在请求的周期的很早的时候就被处理了,所以你不能使用symfony内建的方法或者函数。

CAUTION 在生产环境,配置文件会被缓存,所以配置文件只会在清除缓存后被处理(并执行)一次。

TOP

浏览你的YAML文件 Browsing Your Own YAML File

如果你想直接读取YAML文件,你可以使用sfYaml类。它是一个可以把YAML文件转化成PHP数组的YAML解析器。例5-22是一个YAML文件的例子,例5-23是前面YAML文件的解析结果。

例 5-22 - test.yml
house:
  family:
    name:     Doe
    parents:  [John, Jane]
    children: [Paul, Mark, Simone]
  address:
    number:   34
    street:   Main Street
    city:     Nowheretown
    zipcode:  12345

例 5-23 - 使用sfYaml类把YAML转换成一个数组
[php]
$test = sfYaml::load('/path/to/test.yml');
print_r($test);

Array(
  [house] => Array(
    [family] => Array(
      [name] => Doe
      [parents] => Array(
        [0] => John
        [1] => Jane
      )
      [children] => Array(
        [0] => Paul
        [1] => Mark
        [2] => Simone
      )
    )
    [address] => Array(
      [number] => 34
      [street] => Main Street
      [city] => Nowheretown
      [zipcode] => 12345
    )
  )
)

TOP

总结 Summary

symfony配置系统使用的YAML语言简单并且可读性强。多种环境与层叠结构的参数定义为开发者提供了多种选择。一些配置文件可以从代码里通过sfConfig类访问,特别是app.yml里的应用程序配置。

的确,symfony有很多配置文件,不过这使symfony适用性更强。注意除非你的应用程序需要高级别的定制你根本不需要去修改它们。

TOP

 418 12
发新话题