我想在我的AppBundle中添加配置条目(使用Symfony 3.0.3)。
尽管我努力坚持使用文档示例并在SO上寻找修复程序,但我仍然遇到以下异常,但仍无法发现错误。
YamlFileLoader.php第368行中的InvalidArgumentException:
没有可以加载“app”配置的扩展程序 (在/.../src/AppBundle/DependencyInjection中 /../Resources/config/config.yml)。寻找命名空间“app”,找不到
存在线程/文章,但没有提出实际修复它的解决方案。一些细节可能会突出一英里,我希望有人会在我花费数小时的时间立即发现它们。
我首先设置了配置文件
我猜“app”键应该是okey,因为doc期望名称是小写的包名称, bundle 部分被剥离。对吗?
# AppBundle/Resources/config/config.yml
app:
paginator:
items_per_page: 3
然后我在DependencyInjection命名空间内设置加载/设置过程所需的php类......
配置类文件:
# /src/AppBundle/DependencyInjection/Configuration.php
namespace AppBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('app');
$rootNode
->children()
->arrayNode('paginator')
->performNoDeepMerging()
->addDefaultsIfNotSet()
->children()
->integerNode('items_per_page')
->defaultValue(5)
->isRequired()
->cannotBeEmpty()
->end()
->end()
->end()
->end();
return $treeBuilder;
}
}
扩展类文件:
相应地命名为doc。
# /src/AppBundle/DependencyInjection/AppExtension.php
namespace AppBundle\DependencyInjection;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\Config\FileLocator;
class AppExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$loader = new YamlFileLoader(
$container,
new FileLocator(__DIR__.'/../Resources/config')
);
$loader->load('config.yml');
$processor = new Processor();
$configuration = new Configuration();
$config = $processor->processConfiguration($configuration, $configs);
}
}
堆栈跟踪
in YamlFileLoader.php line 368
at YamlFileLoader->validate(array('app' => array('paginator' => array('items_per_page' => '3'), 'mailer' => array('sender_name' => 'no-reply', 'sender_address' => '%mailer_user%'))), '/../project/src/AppBundle/DependencyInjection/../Resources/config/config.yml') in YamlFileLoader.php line 338
at YamlFileLoader->loadFile('/../project/src/AppBundle/DependencyInjection/../Resources/config/config.yml') in YamlFileLoader.php line 44
at YamlFileLoader->load('config.yml') in AppExtension.php line 21
at AppExtension->load(array(array()), object(ContainerBuilder)) in MergeExtensionConfigurationPass.php line 55
at MergeExtensionConfigurationPass->process(object(ContainerBuilder)) in MergeExtensionConfigurationPass.php line 39
at MergeExtensionConfigurationPass->process(object(ContainerBuilder)) in Compiler.php line 107
at Compiler->compile(object(ContainerBuilder)) in ContainerBuilder.php line 545
at ContainerBuilder->compile() in Kernel.php line 477
at Kernel->initializeContainer() in Kernel.php line 117
at Kernel->boot() in Kernel.php line 166
at Kernel->handle(object(Request)) in app_dev.php line 30
谢谢。
答案 0 :(得分:0)
事实证明,我并不是真的了解整个过程。让我们清楚一点。
目标是公开服务并让dev能够自定义参数/依赖项。
如果那不是你的意思,请浏览SO,真相就在那里 当您希望发布捆绑包时,这种捆绑配置确实很有意义。 AppBundle不太可能被共享。我个人想要提高技能。
加载的配置文件应包含公共服务声明。它也可能设置了一些参数
如果要设置类似数组的属性,请声明“flattened”参数键。 Container的parameterBag不足以遍历数组树。因此$this->getParameter('my_bundle.foo_array.sub_key')
不会导致检索$parameters['mybundle']['foo_array']['sub_key']
,而是检索$parameters['my_bundle.foo_array.sub_key']
。
# AppBunble/Resources/config/config.yml
parameters:
# Prepending a custom namespace may help keep things clearer but is not required
my_ns.foo_property: "@foo_service"
my_ns.bar_property: "bar_value"
my_ns.array_key.baz_property: "baz_value"
my_ns.array_key.qux_property: "qux_value"
你可以声明通常的方式和缩进子键(使用yaml),但在这种情况下,它必须在bundle的Extension类中“展平”(见下文)。
这些参数可以作为配置服务的默认值。
# AppBunble/Resources/config/services.yml
services:
app.my_service:
class: AppBundle\Services\MyService
arguments: ['%my_ns.foo_property%', {"address" : '%ns.array_key.baz_property%', "name":'%ns.array_key.qux_property%'}]
此时,您在MyBunble/Resources/config/*
必须收集默认参数并将其注入容器(使用Symfony \ Component \ DependencyInjection \ Loader \ YamlFileLoader或..XMLFileLoader等帮助程序。)。
$loader = new YamlFileLoader( $container, new FileLocator(__DIR__.'/../Resources/config') );
$loader->load('config.yml');
// ...
$loader->load('services.yml');
第一个参数 array $ configs 保存我们的bundle的公共选项覆盖。它的内容来自app主“配置”文件。用户可以在config.yml和config_dev.yml中设置选项,然后$ configs将显示2个条目。无论如何,$ configs是你必须寻找开发人员可能设置的一些选项的地方。
app:
foo_property: 'some value'
array_key:
qux_property: "jd@mydomain.com"
如果它不为空,则必须在Configuration类的帮助下进行验证(例如AppBundle / DependencyInjection / Configuration.php)。
$configOverride = $this->processConfiguration( new Configuration() , $configs);
Configuration类。
namespace AppBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('app');
$rootNode
->children()
// ...
->end();
return $treeBuilder;
}
}
“app”是symfony希望查找的根密钥,以便填充AppExtension::load
$configs
参数。按照惯例,它是捆绑包名称的蛇形版本,减去“捆绑”后缀。它可以自定义,但您可以设置一些方法覆盖,以获取更多信息see documention。
验证自定义选项后,您可以合并默认值,转换,覆盖等等。最后,您需要将结果选项设置为容器参数。只要容器尝试实例化您的服务,就会使用这些选项。
class AppExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$loader = new YamlFileLoader( $container, new FileLocator(__DIR__.'/../Resources/config') );
$loader->load('config.yml');
// Merging datas…
$container->setParameter('app', $resultingConfig);
$loader->load('services.yml');
注意:我使用的是Sf 3.0.3 我希望这会有所帮助。