417 12
发新话题
打印

管理symfony 配置文件 - Mastering symfony's configuration files

定制文件结构 Customizing the File Structure

如果用户的程序(application)已经有了一个目录结构或者不想采用symfony的目录结构,你可以修改默认的项目文件结构。只要用sfConfig重载sf_XXX_dir和sf_XXX_dir_name变量, 就可以获得一个与默认结构完全不同的文件结构。最适合修改的文件是程序(application)的config.php文件。

CAUTION 要用程序(application)的config.php而不是项目的config.php去重载sf_XXX_dir 和sf_XXX_dir_name. 因为项目的config/config.php文件很早就被载入, 而此时sfConfig类尚不存在, 而且constants.php文件也还未载入。

例如, 如果想让所有的程序(application)能共享模板结构的共用目录,将myapp/config/config.php中的sf_app_template_dir参数修改如下:
[php]
sfConfig::set('sf_app_template_dir', sfConfig::get('sf_root_dir').DIRECTORY_SEPARATOR.'templates');

注意, 程序(application)的config.php文件是非空的, 所以要将文件结构定义加在文件的最后。

TOP

修改项目的根目录 Modifying the Project Web Root

在前端控制器中用常量SF_ROOT_DIR定义了项目根目录,而constants.php中的所有路径都和这个根目录有关。通常根目录是web/目录的上一级目录, 但是你可以用不同的目录结构。假如你的主要目录结构由表19-5的两个目录组成, 就象在一个共享主机上部署项目一样, 包括一个公用目录和一个私有目录。

表19-5 共享主机的定制目录结构示例
symfony/    # 私有区域
  apps/
  batch/
  cache/
...
www/        # 共用区域
  images/
  css/
  js/
  index.php

在这个例子中, symfony/是根目录, 所以在前端控制器index.php中要如下定义SF_ROOT_DIR :
[php]
define('SF_ROOT_DIR', dirname(__FILE__).'/../symfony');

另外, 因为公共目录在www/下, 而不是在通常的web/下, 所以要在config.php中重新定义两个文件路径:

sfConfig::add(array(
  'sf_web_dir'      => SF_ROOT_DIR.DIRECTORY_SEPARATOR.'www',
  'sf_upload_dir'   => SF_ROOT_DIR.DIRECTORY_SEPARATOR.'www'.DIRECTORY_SEPARATOR.sfConfig::get('sf_upload_dir_name'),
));

TOP

连接symfony库 Linking to Symfony Libraries

在config.php文件中定义了框架文件路径, 如表19-6所示。 表19-6 框架文件路径, myproject/config/config.php
[php]
<?php

// symfony directories
$sf_symfony_lib_dir  = '/path/to/symfony/lib';
$sf_symfony_data_dir = '/path/to/symfony/data';

当你从命令行调用symfony init-projec时, symfony初始化这些用于创建一个项目的安装文件的路径。命令行和MVC架构都会用到这些路径。

如果你改变指向框架文件的路径, 你就可以切换到另一个symfony的安装上去。

路径应该是绝对路径, 但是用dirname(FILE), 你可以在项目结构内部引用文件并且为项目安装保留选定目录的独立。例如, 许多项目选取symfony的lib/目录作为项目的lib/symfony/目录的符号链接, 对symfony的data/目录也同样如此:
myproject/
  lib/
    symfony/ => /path/to/symfony/lib
  data/
    symfony/ => /path/to/symfony/data

在这种情况下, 只需在config.php中如下定义symfony目录即可:
[php]
$sf_symfony_lib_dir  = dirname(__FILE__).'/../lib/symfony';
$sf_symfony_data_dir = dirname(__FILE__).'/../data/symfony';

如果你在项目的lib/vendor目录中包括symfony文件作为一个svn:externals, 可以采用同样的方法:
myproject/
  lib/
    vendor/
      svn:externals symfony http://svn.symfony-project.com/trunk/

这样, config.php应该如下所示:
[php]
$sf_symfony_lib_dir  = dirname(__FILE__).'/../lib/vendor/symfony/lib';
$sf_symfony_data_dir = dirname(__FILE__).'/../lib/vendor/symfony/data';v

TIP 有时在运行同一个程序(application)的不同服务器中, symfony库的路径不同。如果要能这样, 一种方法是将config.php文件从同步定义(rsync_exclude.txt)中删除掉, 另一种方法是在开发环境和生产环境中保留同样的config.php路径, 但是根据不同的服务器改变路径的符号链接。
理解配置句柄 Understanding Configuration Handlers

每个配置文件都有一个句柄。配置句柄的任务就是管理配置的级联, 并且在配置文件和运行时优化的PHP可执行代码之间进行转换。

TOP

默认的配置句柄 Default Configuration Handlers

$sf_symfony_data_dir/config/config_handlers.yml中存放默认的配置句柄。该文件根据文件路径来链接配置文件的句柄。表19-7显示了这个文件的摘要。

表19-7 $sf_symfony_data_dir/config/config_handler.yml文件摘要
config/settings.yml:
  class:    sfDefineEnvironmentConfigHandler
  param:
    prefix: sf_

config/app.yml:
  class:    sfDefineEnvironmentConfigHandler
  param:
    prefix: app_

config/filters.yml:
  class:    sfFilterConfigHandler

modules/*/config/module.yml:
  class:    sfDefineEnvironmentConfigHandler
  param:
    prefix: mod_
    module: yes

handlers.yml用一个带通配符的文件路径来标识每个配置文件, 在class关键字下指明句柄的类。

在程序中, 由sfDefineEnvironmentConfigHandler处理的配置文件的参数,可以直接由sfConfig类和包含一个前缀值的参数键来直接操作。

你可以增加和修改用于处理配置文件的的句柄, 例如, 可以用INI或XML文件, 而不用YML文件。

NOTE config_handlers.yml文件的配置句柄是sfRootConfigHandler, 而且不可更改。

如果你想改变编译配置的方法, 在config/目录下创建一个空config_handlers.yml文件, 然后将你自己写的类替换到class行里即可。

TOP

加入你自己的句柄 Adding Your Own Handler

用一个句柄来处理一个配置文件有以下两个重要的好处: 配置文件将被转化为可执行的PHP代码, 而这些代码存放在缓存。也就是说, 在生产环境中配置仅被编译一次, 因而性能是最优。

配置文件可以在项目或文件级别上定义, 并且最终将从不同级别的定义中得到参数。因此, 你可以在项目一级定义参数, 然后在程序(application)的级别上重新设定这些参数。

如果你想写你自己的配置句柄, 在$sf_symfony_lib_dir/config目录中有一个用于框架的结构示例可供参考。

我们假设你的程序(application)中包含一个myMapAPI类(表19-8), 用于为第三方的发送地图web服务提供接口。这个类需要用一个URL和一个用户名去初始化。

表19-8 myMapAPI类的初始化示例
[php]
$mapApi = new myMapAPI();
$mapApi->setUrl($url);
$mapApi->setUser($user);

你可以在程序(application)的config目录下创建一个定制的配置文件map.yml, 文件中存放两个参数:
api:
  url:  map.api.example.com
  user: foobar

为了将这些参数设置转化为等同于表19-8的代码, 你必须构造一个配置句柄。每个配置句柄必须继承sfConfigHandler并且实现一个execute()方法, 这个方法将一个元素为配置文件的路径的数组作为参数,并返回写入缓存文件的数。YAML文件的句柄必须继sfYamlConfigHandler类, 这个类提供了编译YAML的额外的工具。于map.yml文件, 典型的配置句柄应该如下表19-9的示例所示, 文件路径是myapp/lib/myMapConfigHandler.class.php:

表19-9 [php]
class myMapConfigHandler extends sfYamlConfigHandler
{
  public function execute($configFiles)
  {
    $this->initialize();

    // Parse the yaml
    $config = $this->parseYamls($configFiles);

    $data  = "<?php\n";
    $data. = "\$mapApi = new myMapAPI();\n";

    if (isset($config['api']['url'])
    {
      $data. = sprintf("\$mapApi->setUrl('%s');\n", $config['api']['url']);
    }

    if (isset($config['api']['user'])
    {
      $data. = sprintf("\$mapApi->setUser('%s');\n", $config['api']['user']);
    }

    return $data;
  }
}

symfony传递$configFiles数组给execute()方法, 该数组包含一个指向config/目录中的所有map.yml文件的路径.parseYamls()方法处理配置级联。

为了让这个新的句柄能与map.yml协同工作, 你必须创建一个包括如下内容大config_handlers.yml配置文件:
config/map.yml:
  class: myMapConfigHandler

NOTE 这个类要么被自动载入(如本例所示), 要么在一个文件中定义, 该文件的路径记录文件参数的param关键字下。

当你需要基于map.yaml文件由myMapConfigHandler句柄生成的代码的时候。执行下面的代码:
[php]
include(sfConfigCache::getInstance()->checkConfig(sfConfig::get('sf_app_config_dir_name').'/map.yml'));

调用checkConfig()方法时, 如果缓存里没有map.yml.php或者map.yml比缓存中的更新, 那么, symfony在配置目录中寻找现存的map.yml文件, 并用config_handlers.yml中指明的句柄来处理这些文件。

TIP 如果要在一个YAML配置文件中处理环境变量, 你可以继承sfDefineEnvironmentConfigHandler类, 而不是继承sfYamlConfigHandler。在调用parseYaml()方法遍历了配置以后, 你需要调用mergeEnvironment()方。你可以在一条代码行里完成所有任务:$config = $this->mergeEnvironment($this->parseYamls ($configFiles));

-

SIDEBAR 使用现成的配置句柄

如果你仅想让用户通过sfConfig从代码中遍历值, 你可以使用sfDefineEnvironmentConfigHandler配置句柄。例如, 要实现sfConfig::get(‘map_url’)和sfConfig::get(‘map_user’), 你可以如下定义你的句柄:
config/map.yml:
  class: sfDefineEnvironmentConfigHandler
  param:
    prefix: map_

注意不要使用已经被别的句柄使用过的前缀, 现有的前缀包括sf_, app_和mod_。

TOP

控制PHP参数 Controlling PHP Settings

为了让PHP环境和敏捷开发的原则及实践相配合, symfony检测并修改了php.ini中的有些参数。php.yml文件就是为了这个目的而出现。

表19-10是默认的php.yml文件的内容, 该文件在$sf_symfony_data_dir/config下。
set:
  magic_quotes_runtime:        off
  log_errors:                  on
  arg_separator.output:        |
    &

check:
  zend.ze1_compatibility_mode: off

warn:
  magic_quotes_gpc:            off
  register_globals:            off
  session.auto_start:          off

这个文件的主要目的就是检测php配置是否和你的程序(application)兼容, 也可用于检测你的开发服务器配置是否和生产服务器足够相似。在项目开始时, 检查生产服务器的配置, 将配置放进php.yml文件中, 这样你在开发和测试时就有信心确保将项目部署到生产环境时不会遇到兼容性错误。

不管服务器的php.ini文件如何定义, 都应该修改定义在set部分的变量,而warn部分的变量则不需要修改, 不过即使参数设置得不对, symfony仍旧能正常运行。如果不幸将warn中的参数都设置为off, 则symfony将记录一个警告日。 check部分的参数也无需修改, 但是为了symfony能运行, 必须为它们设置一个值。如果php.ini设置错误, 将会抛出一个异常。

默认的php.yml文件将log_errors设置为on, 因而你可以在symfony项目中追踪错。建议将register_globals设置为off, 以免留下安全漏洞。

如果你不希望symfony采取这些参数, 或者你想将magic_quotes和register_globals设置为on而不发出警告, 那就在你的程序(application)的config目录下创建一个php.yml文件,并且用你所要的值来设定那些参数。

另外, 如果你的项目需要一个PHP扩展, 你可以在扩展分类中使用如下的数组来指明:
extensions: [gd, mysql, mbstring]

TOP

总结 Summary      配置文件对框架的运行有重要的影。因为symfony的核心特性和文件加载都依赖于配置, 所以它能适应许多不同的环境, 而不仅仅是标准环境。symfony的重要特点就是它的高可配置性。尽管这么多配置文件和一大堆规定会吓坏初学者, 但是它确实可以让symfony程序(application)可以适用于大量的平台和环境。一旦你掌握了symfony配置, 你的程序(application)将可运行在任意服务器上. [希望对大家有用,谢谢~~~]

TOP

 417 12
发新话题