[英]Silex PHP - How to populate $app with dynamic keys from custom service provider after register()
I'm the developer for m1/vars , which is a config loader service provider for Silex, what I want to know to make my library more useful is how to go about dynamically loading keys into $app
after registering the service and dealing with the secondary parameters of $app->register()
. 我是开发商M1 /增值经销商 ,这是一个Silex的配置装载机服务提供商,我想知道让库更有用的是如何去动态加载项为$app
注册服务和处理后$app->register()
辅助参数。
For example this is how it currently works: 例如,这是当前的工作方式:
app.php: app.php:
$app->register(new M1\Vars\Provider\Silex\VarsServiceProvider('example.yml'), [
'vars.path' => __DIR__,
'vars.options' => [
// options here
]
]);
$app['vars.merge']();
VarsServiceProvider.php: 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;
}
});
What this basically does is it loads the stuff from the config file ( example.yml
) lazily -- so when accessing $app['vars']
it loads -- so the $app['vars.options']
will be available as it has already been defined in the second parameter of register()
. 这基本上是从配置文件( example.yml
)懒惰地加载东西-因此在访问$app['vars']
它会加载-因此$app['vars.options']
将作为它已经在register()
的第二个参数中定义。 $app['vars.merge']
loads the data from $app['vars']
into $app
, for example if you defined: $app['vars.merge']
将数据从$app['vars']
$app['vars.merge']
加载到$app
,例如,如果您定义:
example.yml example.yml
monolog.logfile: %dir%/../../app/logs/app/dev.log
After $app['vars.merge']()
you could then load the above from $app['monolog.logfile']
instead of $app['vars']['monolog.logfile']
在$app['vars.merge']()
您可以从$app['monolog.logfile']
而不是$app['vars']['monolog.logfile']
What I'm aiming for is getting rid of $app['vars.merge']
as it doesn't seem right to me and seems a bit hacky but the problem is the $app['vars.options']
and $app['vars.path']
have to be available for $app['vars']
and I don't want to have to call $app['vars']
before I can call $app['vars.monolog.logfile']
. 我想要的是摆脱$app['vars.merge']
因为它对我来说似乎不正确,看起来有些hacky,但问题是$app['vars.options']
和$app['vars.path']
必须可用于$app['vars']
,在我可以调用$app['vars.monolog.logfile']
之前,我不想调用$app['vars']
$app['vars.monolog.logfile']
。
Any ideas, if it doesn't make sense I'll try and explain a bit more? 有什么想法,如果没有意义的话,我会尝试解释更多吗?
Thanks. 谢谢。
If I got you right, why don't you just call app['vars.merge']
directly from your provider? 如果我说对了,为什么不直接从您的提供商那里直接调用app['vars.merge']
? In fact, you could avoid the vars.merge
function and just call the for each inside the register function. 实际上,您可以避免使用vars.merge
函数,而只需在register函数中为每个函数调用。
In order to make your provider more Silex friendly I would probably implement the foreach inside the boot method of your provider. 为了使您的提供程序对Silex更友好,我可能会在提供程序的boot方法内部实现foreach。
The signature from this method is simple: public function boot(Application $app);
此方法的签名很简单: public function boot(Application $app);
and the docs may me think that this is what you probably want: 而文档可能让我认为这可能就是您想要的:
Bootstraps the application. 引导应用程序。
This method is called after all services are registered and should be used for "dynamic" configuration (whenever a service must be requested). 在注册所有服务之后,将调用此方法,并且应将其用于“动态”配置(每当必须请求服务时)。
So your boot method should look like: 因此,您的启动方法应如下所示:
<?php
// ...
class VarsServiceProvider implements ServiceProviderInterface
{
// ...
public function boot(Application $app)
{
foreach ($app['vars']->toDots(false) as $key => $value) {
$app[$key] = $value;
}
}
}
My main concern with the boot method is that the parameters will be loaded once the application is booted which may be a little too late in some circumstances, you should do some research about that (it that's the case then just put the foreach inside the register
method). 我对启动方法的主要担心是,一旦启动应用程序,参数将被加载,在某些情况下可能为时已晚,您应该对此进行一些研究(在这种情况下,只需将foreach放入register
方法)。
Seeing that none of this options are valid for your use case, what about defining your service like so? 看到所有这些选项都不适合您的用例,那么像这样定义您的服务呢?
<?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;
};
Hope that helps. 希望能有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.