Php Symfony2:自定义配置根目录
我的应用程序由多个bundle组成,这些bundle的名称类似于Php Symfony2:自定义配置根目录,php,symfony,Php,Symfony,我的应用程序由多个bundle组成,这些bundle的名称类似于HelloWorldAdminBundle,HelloWorldUserBundle,HelloWorldDemoBundle。这将产生一个配置根目录,如hello\u world\u demo、hello\u world\u user和hello\u world\u demo。我希望捆绑包的配置根是helloworld\u demo,helloworld\u user和helloworld\u admin。在这一点上,我必须提到,
HelloWorldAdminBundle
,HelloWorldUserBundle
,HelloWorldDemoBundle
。这将产生一个配置根目录,如hello\u world\u demo
、hello\u world\u user
和hello\u world\u demo
。我希望捆绑包的配置根是helloworld\u demo
,helloworld\u user
和helloworld\u admin
。在这一点上,我必须提到,这不是一个真正的技术问题,而是一个美学问题
我已尝试实现自定义扩展并将其注册到捆绑包中:
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->registerExtension(new HelloworldDemoExtension());
}
延长期限:
...
class HelloworldDemoExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
public function getAlias()
{
return 'hello_world_demo';
}
}
最后是配置:
...
class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('helloworld_demo');
...
return $treeBuilder;
}
}
我按照说明进行操作,但是,当我向config.yml
添加一个项目时,出现以下错误:
There is no extension able to load the configuration for "helloworld_demo"
正如上面所说:
创建扩展时,请遵循以下简单约定:
- 扩展必须存储在DependencyInjection子命名空间中李>
- 扩展名必须以包名命名,并以扩展名作为后缀(AcmeHelloExtension代表AcmeHelloBundle)李>
- 扩展应该提供一个XSD模式
build
和getAlias
方法。若您需要它,那个么getAlias
方法应该返回和您在根节点中定义的相同的值。所以它应该是helloworld\u demo,而不是书中的hello\u world\u demo
“在这种情况下,扩展类还必须实现getAlias()方法,并返回以捆绑包命名的唯一别名(例如acme_hello)。这是必需的,因为类名以扩展结尾不符合标准。
此外,仅当用户在至少一个配置文件中指定acme_hello别名时,才会调用扩展名的load()方法。”
因此,此别名是根配置名称。将代码更改为
public function getAlias()
{
return 'helloworld_demo';
}
而且它应该会起作用我找到了解决问题的办法。它的工作原理与我在问题中描述的完全相同,但是,必须存在一个默认扩展名(带有捆绑包的名称)
我现在有一个名为HelloWorldDemoExtension的空扩展名(别名为
hello\u world\u demo
),而且我还添加了DemoExtension(别名为helloworld\u demo
),它可以工作。我通过重写解决了这个问题
此方法自动创建并返回ExtensionInterface
的实例,还检查扩展的别名(根据答案,可以通过在扩展类中实现getAlias
来指定)是否符合命名约定
因此,通过重写bundle类中的getContainerExtension()
方法,只需返回扩展类的实例,就可以绕过检查和LogicException
这是您的bundle类的外观:
<?php
namespace HelloWorld\Bundle\UserBundle;
use HelloWorld\Bundle\UserBundle\DependencyInjection\HelloWorldUserExtension;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class HelloWorldUserBundle extends Bundle
{
public function getContainerExtension()
{
if (null === $this->extension) {
$this->extension = new HelloWorldUserExtension();
}
return $this->extension;
}
}
警告:我不确定为什么要将此检查添加到getContainerExtension()
方法中。这可能是一个非常合理的原因,您在执行上述步骤时可能会遇到问题。但是,到目前为止,我还没有遇到任何问题
编辑:另请参阅:。这篇博客文章提供了与我的答案相同的解决方案。另外,请参阅Symfony的文档,其中也描述了相同的方法。这使我相信这样做是安全的,而无需预期副作用。否。就我对文档的理解而言,
getAlias
方法是我们的由Symfony编辑以将扩展与捆绑包关联。由于扩展名不再提供捆绑包的任何提示,因此使用别名。编辑:这在语义配置文档页面的底部进行了解释:关于第一部分。我知道这些约定,为了美观,我想打破它们。 [LogicException]捆绑包的默认扩展名的扩展别名必须是捆绑包名称的下划线版本(“hello\u world\u demo”而不是“helloworld\u demo”)
mmm…因此,我想剩下的唯一解决方案是将您的捆绑包重命名为HelloworldDemoBundle,等等…这很难看,但我想如果您真的想打破symfony的惯例,那就是最好的方法。最干净的方法必须是正确命名您的捆绑包:-)@AlainTiemblo正确命名捆绑包并不总是可行的-CMSIP2LocationBundle
。
/**
* The extension alias
*
* @return string
*/
public function getAlias()
{
return 'helloworld_user';
}