“无法加载”

时间:2016-04-26 18:32:05

标签: symfony dependency-injection

我想在我的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

谢谢。

1 个答案:

答案 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/*

内的多个文件之间声明,分割或不分割参数和服务 那么什么?由于您公开了服务,因此使用您的软件包的开发者可能希望提供替代配置。您的工作是在捆绑包的扩展(例如AppBundle / DependencyInjection / AppExtension.php)中实现。一切都发生在加载方法中。

  • 必须收集默认参数并将其注入容器(使用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 我希望这会有所帮助。