[译文] symfony 参考指南 – 配置文件原则

原文:the symfony Reference Book, http://www.symfony-project.org/reference/1_2/en/03-Configuration-Files-Principles
翻译:ELEME Dev Team

symfony 所有的的配置文件都基于一套共同的原则,并使用一些公共属性。本节将详细地介绍这些原则和属性,并且可为后面几个关于YAML配置文件的章节提供参考。

缓存

symfony 的配置处理类会将所有的配置文件缓存为 PHP 文件。当 is_debug 属性设置为 false 时 (例如在 prod 环境中,即生产环境),symfony 仅会在首次请求中对配置文件进行缓存处理,而在这之后的所有请求都将访问相应的 PHP 缓存文件。对 YAML 文件的解析是一个较“重”的处理过程,缓存机制使得这个过程只执行一次。

dev 环境(即开发环境)下, is_debug 属性默认设置为 true,symfony 将在每一次配置变化后重新分析处理缓存(symfony 会检查文件的修改时间)。

可以通过 config_handler.yml 文件来配置解析和处理配置文件所需的配置处理类(configuration handler class)。

在以下各节中,我们称 symfony 将 YAML 文件转化为 PHP 文件并存储在缓存中的这一过程为“编译”。

要强制清空配置缓存可以使用 cache:clear 命令:

$ php symfony cache:clear --type=config

常量

配置文件core_compile.ymlfactories.ymlgenerator.ymldatabases.ymlfilters.ymlview.ymlautoload.yml

一些配置文件允许使用预先定义的常量。symfony 通过占位符来使用常量,即在大写的常量名两侧加上“%”符号,类似于“%XXX%”。当配置文件被编译时,symfony 会用常量的实值去替换掉所有相应的占位符。

使用配置文件中的常量

settings.yml 中定义的任何设置都可以作为常量来使用。其占位符为大写的设置名称并在开头加上 SF_

logging: %SF_LOGGING_ENABLED%

当 symfony 编译配置文件时,它会从 settings.yml 文件中读取常量的值并替换掉占位符。在上面的例子中,symfony 会在 settings.yml 中查找 logging_enabled 这一设置,并用其值来替换占位符 SF_LOGGING_ENABLED

使用应用程序设置文件中的常量

与使用 settings.yml 文件中的常量类似,可以通过添加 APP_ 的前缀来使用 app.yml 中的设置。

特殊常量

默认情况下, symfony 根据当前的前端控制器定义了四个常量:

常量 描述 配置方法
SF_APP 当前应用程序名称 getApplication()
SF_ENVIRONMENT 当前环境名称 getEnvironment()
SF_DEBUG 是否启用调试 isDebug()
SF_SYMFONY_LIB_DIR symfony 库目录 getSymfonyLibDir()

文件和目录

当你需要引用一个文件或目录地址时,使用常量而不是硬编码是个很不错的主意。symfony 已经为一些公共目录定义了对应的常量。

SF_ROOT_DIR 对应于 symfony 目录树中的根目录,其余所有目录变量都通过这一变量产生。

项目目录结构的常量定义如下:

常量 默认值
SF_APPS_DIR SF_ROOT_DIR/apps
SF_CONFIG_DIR SF_ROOT_DIR/config
SF_CACHE_DIR SF_ROOT_DIR/cache
SF_DATA_DIR SF_ROOT_DIR/data
SF_DOC_DIR SF_ROOT_DIR/doc
SF_LIB_DIR SF_ROOT_DIR/lib
SF_LOG_DIR SF_ROOT_DIR/log
SF_PLUGINS_DIR SF_ROOT_DIR/plugins
SF_TEST_DIR SF_ROOT_DIR/test
SF_WEB_DIR SF_ROOT_DIR/web
SF_UPLOAD_DIR SF_WEB_DIR/uploads

应用程序目录结构是根据 SF_APPS_DIR/APP_NAME 所定义的:

常量 默认值
SF_APP_CONFIG_DIR SF_APP_DIR/config
SF_APP_LIB_DIR SF_APP_DIR/lib
SF_APP_MODULE_DIR SF_APP_DIR/modules
SF_APP_TEMPLATE_DIR SF_APP_DIR/templates
SF_APP_I18N_DIR SF_APP_DIR/i18n

最后,应用程序的缓存目录结构定义如下:

常量 默认值
SF_APP_BASE_CACHE_DIR SF_CACHE_DIR/APP_NAME
SF_APP_CACHE_DIR SF_CACHE_DIR/APP_NAME/ENV_NAME
SF_TEMPLATE_CACHE_DIR SF_APP_CACHE_DIR/template
SF_I18N_CACHE_DIR SF_APP_CACHE_DIR/i18n
SF_CONFIG_CACHE_DIR SF_APP_CACHE_DIR/config
SF_TEST_CACHE_DIR SF_APP_CACHE_DIR/test
SF_MODULE_CACHE_DIR SF_APP_CACHE_DIR/modules

环境

配置文件settings.ymlfactories.ymldatabases.ymlapp.yml

某些配置文件与 symfony 的当前环境有关。这些文件通过划分不同的区段,为每个环境设置不同的配置。当创建一个新的应用时,symfony 会创建三个默认的环境:prod(生产环境),test(测试环境),和 dev(开发环境):

prod:
  # `prod` 环境的配置

test:
  # `test` 环境的配置

dev:
  # `dev` 环境的配置

all:
  # 所有环境公用的默认配置

all 区段为所有的环境提供默认设置。当 symfony 从配置文件中读取一个设置时,它会优先使用相应环境区段中的配置,若当前环境区段中没有提供该设置,则 symfony 会在 all 区段去寻找它。

配置的级联

配置文件core_compile.ymlautoload.ymlsettings.ymlfactories.ymldatabases.ymlsecurity.ymlcache.ymlapp.ymlfilters.ymlview.yml

有时候,同一个配置文件可以在几个不同的 config 目录多次出现,symfony 会按照目录结构合并它们。

symfony 在编译配置文件的时候,会根据以下顺序先后合并多个文件中的配置信息:

  • 模块配置( PROJECT_ROOT_DIR/apps/APP_NAME/modules/MODULE_NAME/config/XXX.yml
  • 应用程序配置( PROJECT_ROOT_DIR/apps/APP_NAME/config/XXX.yml
  • 项目配置( PROJECT_ROOT_DIR/config/XXX.yml
  • 插件配置( PROJECT_ROOT_DIR/plugins/*/config/XXX.yml
  • symfony 库配置( SF_LIB_DIR/config/XXX.yml

例如,在一个应用程序目录中定义的 settings.yml 将默认继承这个应用程序所在项目的 config 目录中 settings.yml 的配置信息,而项目的 settings.yml 又是继承自 symfony 框架的默认 settings.yml 配置文件中的配置信息(lib/config/config/settings.yml)。

当一个配置文件与环境相关,并在多个目录中,那么则按照下面给出的优先级来合并配置:

  1. 模块
  2. 应用程序
  3. 项目
  4. 特定环境
  5. 所有环境
  6. 默认值

[译文] symfony 参考指南 – YAML 基础

原文:the symfony Reference Book, http://www.symfony-project.org/reference/1_2/en/02-YAML
翻译:ELEME Dev Team

大多数的symfony配置文件使用YAML格式。YAML 官方网站称 YAML 是“一种所有编程语言可用的友好的数据序列化标准”。

YAML 是一种轻量化的数据描述语言。类似于 PHP, YAML一样具有轻量化的语法与数据类型,如字符串、布尔型、浮点型或整数型等。但不同于PHP的是,它区分数组(序列)和散列表(哈希表) 。

尽管 YAML 格式能够描述更为复杂的嵌套的数据结构,本节仅描述你在 symfony 中使用 YAML 作为配置文件所需要了解的 YAML 最小功能集。

基础类型

YAML 基础类型语法与PHP中的相似。

字符串

A string in YAML
'A singled-quoted string in YAML'

在一个单引号标注的字符串中,一个单引号'必须用另一个单引号进行转义:

'A single quote '' in a single-quoted string'
"A double-quoted string in YAML\n"

当一个字符串前后包含空格时,必须使用引号标注的格式。

双引号标注的风格提供了一种使用转义符号\表达任意字符串的方式。当您需要嵌入一个\n或Unicode字符的时候,这是非常有用的。

当一个字符串包含换行符,您可以通过使用|符号表明该字符串将跨越数行,从而使用传统的文本风格。在这种格式下,换行符将不被转义:

|
  \/ /| |\/| |
  / / | |  | |__

或者,字符串可以通过>符号写成这样的折叠式,这样每一个换行符都将被替换成空格:

>
  This is a very long sentence
  that spans several lines in the YAML
  but which will be rendered as a string
  without carriage returns.

请注意:在上面这个例子中,每一行前的两个空格将不会出现在结果的PHP字符串中。

数字

# 整数
12
# 八进制整数
014
#十六进制整数
0xC
#浮点数
13.4
#指数
1.2e+34
#无穷大
.inf

空值

在YAML中,空值可以用null~ 表示。

布尔值

在YAML中,布尔值用truefalse 表示。

尽管 symfony 的 YAML解析器能够把onoffyesno 等解析为布尔值,但是我们强烈反对使用他们,因为它们已经在YAML 1.2标准中被移除。

日期

YAML 使用 ISO-8601 标准表示日期:

2001-12-14t21:59:43.10-05:00
#简单日期示例
2002-12-14

集合

YAML文件很少仅用来描述一个简单的基础类型。大多数时候,它被用来描述一个集合。一个集合可以是一个序列(数组)或散列表(哈希表)。序列和散列表都会被转换成为 PHP 的数组。

使用一个跟着空格的“-”符号来声明一个序列:

- PHP
- Perl
- Python

这相当于下面的PHP代码:

array('PHP', 'Perl', 'Python');

使用一个跟着空格的冒号标记每一个键/值对来声明一个散列表:

PHP: 5.2
MySQL: 5.1
Apache: 2.2.20

这相当于下面的PHP代码:

array('PHP' => 5.2, 'MySQL' => 5.1, 'Apache' => '2.2.20');

在散列表中,键 (key) 可以是任何合法的YAML基础类型。

一个散列项的冒号和值之间必须至少有一个或者更多个空格,而具体的空格数目并不重要:

PHP:    5.2
MySQL:  5.1
Apache: 2.2.20

YAML使用一个或多个空格的缩进来描述嵌套集合:

"symfony 1.0":
  PHP:    5.0
  Propel: 1.2
"symfony 1.2":
  PHP:    5.2
  Propel: 1.3

这段 YAML 代码相当于下面的PHP代码:

array(
  'symfony 1.0' => array(
    'PHP'    => 5.0,
    'Propel' => 1.2,
  ),
  'symfony 1.2' => array(
    'PHP'    => 5.2,
    'Propel' => 1.3,
  ),
);

在YAML文件中使用缩进时必须牢记的一件事情是: 必须使用一个或多个空格进行缩进,而不能使用制表符 (Tab键)

你可以像这样混合使用嵌套的序列和散列表:

'Chapter 1':
  - Introduction
  - Event Types
'Chapter 2':
  - Introduction
  - Helpers

YAML也可以使用流风格的集合,使用明确的标示符而不是缩进进行集合范围的界定。

一个序列可以写成方括号( [] ) 中逗号分隔的列表的形式:

[PHP, Perl, Python]

一个散列表可以写成大括号( {} ) 中逗号分隔的键/值对列表的形式:

{ PHP: 5.2, MySQL: 5.1, Apache: 2.2.20 }

你也可以混合两种风格,以实现更好的可读性:

'Chapter 1': [Introduction, Event Types]
'Chapter 2': [Introduction, Helpers]
"symfony 1.0": { PHP: 5.0, Propel: 1.2 }
"symfony 1.2": { PHP: 5.2, Propel: 1.3 }

注释

YAML 中添加注释的方式是通过井字符(#):

#行末评论
"symfony 1.0": { PHP: 5.0, Propel: 1.2 } # Comment at the end of a line
"symfony 1.2": { PHP: 5.2, Propel: 1.3 }

由于注释会被YAML解析器忽略,因此不必刻意对注释进行缩进。

动态 YAML 文件

在 symfony 中,一个 YAML 文件可以包含 PHP 代码,这部分代码将在 YAML 文件解析前被执行:

1.0:
  version: <?php echo file_get_contents('1.0/VERSION')."\n" ?>
1.1:
  version: "<?php echo file_get_contents('1.1/VERSION') ?>"

注意保持文件的正确缩进格式。当在 YAML 中嵌入 PHP 代码时,应记住以下几点:

  • <?php ?> 语句必须在一行的开始,或作为一个属性的值的一部分
  • <?php ?>在行末,则需要在 php 中输出一个换行符(”\n”)。

一个完整的例子

下面的例子使用了本章中提到的 YAML 语法:

"symfony 1.0":
  end_of_maintainance: 2010-01-01
  is_stable:           true
  release_manager:     "Gregoire Hubert"
  description: >
    This stable version is the right choice for projects
    that need to be maintained for a long period of time.
  latest_beta:         ~
  latest_minor:        1.0.20
  supported_orms:      [Propel]
  archives:            { source: [zip, tgz], sandbox: [zip, tgz] }

"symfony 1.2":
  end_of_maintainance: 2008-11-01
  is_stable:           true
  release_manager:     'Fabian Lange'
  description: >
    This stable version is the right choice
    if you start a new project today.
  latest_beta:         null
  latest_minor:        1.2.5
  supported_orms:
    - Propel
    - Doctrine
  archives:
    source:
      - zip
      - tgz
    sandbox:
      - zip
      - tgz

[译文] symfony 参考指南 – 前言

原文:the symfony Reference Book, http://www.symfony-project.org/reference/1_2/en/01-Introduction
翻译:ELEME Dev Team

作为一名 web 开发人员,提高开发效率的最简便的方式就是使用 symfony 这样的一个全栈化框架 (full-stack framework)。这个框架捆绑实现了许多有用的功能,可以让你把精力集中在程序的业务逻辑上,而不是被各种具体实现上的细节,如分页器对象或者是数据抽象层等的实现所困扰。不过这一切并不是免费午餐:你需要一定时间学习配置 symfony 和掌握它的各种高级特性。

symfony最佳实践 发表在2008年年底,是初学者学习symfony并理解其运作方式的捷径,同时还可以在实践中理解何为最佳web开发方式。

当你开始一个项目时,你需要这样的一本参考书:一本触手可得,可以随时让你找到问题的答案的好的参考指南。这本Symfony参考指南的目的就是提供这样的一份指南。它可以看成是symfony实践手册的补充内容。如果你要用symfony进行开发,那么你就应该有这样的一本书。它有着非常详细的目录和术语表,章节之间的相互参照,详尽的表格等,为您提供了找到symfony每一个可用配置说明的最快方式。

尽管我是symfony的首席开发者,但我仍然不时地使用这本书去寻找某一特定的配置设置,或者只是浏览这本书去重新发现一些被我忽视的技巧。我希望你能像我一样每天都享受它给你带来的快乐。