【问题标题】:Symfony container has no extensions when loading my bundleSymfony 容器在加载我的包时没有扩展
【发布时间】:2015-03-09 08:03:59
【问题描述】:

我有一个在一段时间内运行良好的捆绑包。但是,我必须为其添加一些自定义配置参数,所以我在包的 config.yml 中写了一些行,如下所示:

# ...
acme_my_bundle:
    special_params: ['param_1', 'param_2']

配置在包的Configuration类中定义:

namespace ACME\MyBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

/**
 * This is the class that validates and merges configuration from your app/config files
 *
 * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
 */
class Configuration implements ConfigurationInterface {
    /**
     * {@inheritdoc}
     */
    public function getConfigTreeBuilder() {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root('acme_my_bundle');

        $rootNode
            ->children()
                ->arrayNode('special_params')
                ->end()
            ->end();

        return $treeBuilder;
    }
}

捆绑包已在AppKernel.php 中正确注册:

public function registerBundles() {
    $bundles = array(
        // ...
        new ACME\MyBundle(),
        // ...
    );

    // ...

    return $bundles;
}

但是,当我尝试使用我的应用时,我收到了一个错误:

There is no extension able to load the configuration for "acme_my_bundle" (in (path_to_bundle)/MyBundle/DependencyInjection/../Resources/config/config.yml). Looked for namespace "acme_my_bundle", found none

我查了一下,但发现的大多数结果都不令人满意——我排除了搜索过程中出现的问题:

  • 配置结构不正确
  • bundle 未在应用内核中注册
  • 配置根节点名与ACMEMyBundleExtension::getAlias()返回的不同

我尝试调试引发异常的原因,发现当 YAML 文件加载器尝试验证我的配置文件时,容器没有扩展名:

var_dump($container->getExtensions()); // prints empty array - array(0) { }

这会导致验证失败并显示消息的 none 部分 - 没有可用的扩展。

我尝试在ContainerBuilder::hasExtension() 中调试$this->extensions,由于某种原因,当为供应商捆绑包启动该方法时列表已完成,但对于我的捆绑包是空的。看起来我的包中的某些内容仍然定义或注册不正确。

为了不暴露公司代码,我改了类名等等

编辑:我没有明确提到它,但是 Extension 类是定义的,并且在加载时发生异常 - 正如我在上面写的那样:

当 YAML 文件加载器尝试验证我的配置文件时

为了更清楚,这是我的Extension 类:

namespace ACME\MyBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;

/**
 * This is the class that loads and manages your bundle configuration
 *
 * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
 */
class ACMEMyBundleExtension extends Extension {
    /**
     * {@inheritdoc}
     */
    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'));
        // The exception is thrown here
        $loader->load('config.yml');
    }
}

【问题讨论】:

    标签: php symfony configuration


    【解决方案1】:

    ACME\MyBundle\DependencyInjection\Configuration 中检查您的配置阅读器$rootNode = $treeBuilder->root('BUNDLE_CONFIG_KEY');

    BUNDLE_CONFIG_KEY 应该是:

    • 有效(ACME\MyBundle\DependencyInjection\Configuration 和您的config.yml 相同
    • 应用独有

    另外请检查您是否以正确的方式定义捆绑配置 - 应将其添加到 app/config/*.yml(全局配置文件之一)。也许您在其他自定义捆绑配置文件中添加了acme_my_bundle 配置?

    【讨论】:

    • 就是这样!我在本地包config.yml中添加了配置,真是个愚蠢的错误...
    【解决方案2】:

    您错过了捆绑扩展类 (ACME\MyBundle\DependencyInjection\ACMEMyExtension),如此处 http://symfony.com/doc/current/cookbook/bundles/extension.html 所述。捆绑配置的食谱条目是here。 config.yml 中的键只能命名为 acme_my。

    【讨论】:

    • Extension 已定义,我已更新我的问题以特别提及它
    • 根据我的回答中的链接尝试更改命名约定。 ACMEMyBundleExtension 到 ACMEMyExtension 和 acme_my_bundle 到 acme_my。我认为 Symfony 出于某种原因没有加载您的扩展程序。
    【解决方案3】:

    仅创建Configuration 类是不够的。您需要注册一个依赖注入扩展并在其中使用Configuration 类。

    How to Create Friendly Configuration for a Bundle 食谱中了解更多信息:

    [The Configuration] 类现在可以在您的 load() 方法中用于合并配置和强制验证(例如,如果传递了附加选项,则会引发异常)

    namespace Acme\MyBundle\DependencyInjection;
    
    use Symfony\Component\HttpKernel\DependencyInjection\Extension;
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    
    class AcmeMyBundleExtension extends Extension
    {
        public function load(array $configs, ContainerBuilder $container)
        {
            $configuration = new Configuration();
    
            $config = $this->processConfiguration($configuration, $configs);
            // ...
        }
    }
    

    根据约定命名您的扩展类将使其自动加载。更多关于在Creating an Extension Class 中创建 DIC 扩展类的信息。您也可以手动启用扩展,请参阅Manually registering an extension class

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-06
    • 1970-01-01
    • 1970-01-01
    • 2015-10-28
    • 2012-05-25
    • 2015-08-18
    • 1970-01-01
    相关资源
    最近更新 更多