我是 m1/vars 的开发人员,它是 Silex 的配置加载器服务提供商,我想知道让我的库更有用的是如何在注册服务并处理$app->register()
的辅助参数后将密钥动态加载到$app
中。
例如,这是它目前的工作方式:
应用.php:
$app->register(new M1VarsProviderSilexVarsServiceProvider('example.yml'), [
'vars.path' => __DIR__,
'vars.options' => [
// options here
]
]);
$app['vars.merge']();
VarsServiceProvider.php:
$app['vars'] = function ($app) {
return new Vars($this->entity, $this->createOptions($app));
};
$app['vars.merge'] = $app->protect(function() use ($app) {
static $initialized = false;
if ($initialized) {
return;
}
$initialized = true;
foreach ($app['vars']->toDots(false) as $key => $value) {
$app[$key] = $value;
}
});
这基本上是它懒惰地从配置文件(example.yml
)加载东西 - 所以当访问它加载$app['vars']
- 所以$app['vars.options']
将可用,因为它已经在register()
的第二个参数中定义。 $app['vars.merge']
将数据从$app['vars']
加载到$app
,例如,如果您定义了:
例子.yml
monolog.logfile: %dir%/../../app/logs/app/dev.log
$app['vars.merge']()
后,您可以从$app['monolog.logfile']
加载上述内容,而不是$app['vars']['monolog.logfile']
我的目标是摆脱$app['vars.merge']
,因为它对我来说似乎不对,而且看起来有点笨拙,但问题是$app['vars.options']
,$app['vars.path']
必须可供$app['vars']
使用,我不想在打电话之前打电话给$app['vars']
$app['vars.monolog.logfile']
。
任何想法,如果它没有意义,我会尝试解释更多?
谢谢。
如果我猜对了,你为什么不直接从你的提供者那里打电话给app['vars.merge']
呢?实际上,您可以避免使用 vars.merge
函数,而只需在寄存器函数中调用 for each 即可。
为了使您的提供程序对 Silex 更友好,我可能会在您的提供程序的引导方法中实现 foreach。
此方法的签名很简单:public function boot(Application $app);
和文档可能我认为这是您可能想要的:
引导应用程序。
注册所有服务后调用此方法 并且应该用于"动态"配置(每当 必须请求服务)。
因此,您的引导方法应如下所示:
<?php
// ...
class VarsServiceProvider implements ServiceProviderInterface
{
// ...
public function boot(Application $app)
{
foreach ($app['vars']->toDots(false) as $key => $value) {
$app[$key] = $value;
}
}
}
我对引导方法的主要担忧是,一旦应用程序启动,参数就会加载,这在某些情况下可能有点太晚了,你应该对此做一些研究(就是这种情况,然后只是把foreach放在register
方法中)。
第二次尝试
看到这些选项都不适用于您的用例,那么像这样定义您的服务怎么样?
<?php
// Service Provider
$app['vars'] = function ($app) {
$instance = new Vars($this->entity, $this->createOptions($app));
foreach ($instance->toDots(false) as $key => $value) {
$app[$key] = $value;
}
return $instance;
};
希望有帮助。