加入你自己的句柄 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_。