Symfony 2 -如何解析%参数%在我自己的Yaml文件加载器


Symfony 2 - how to parse %parameter% in my own Yaml file loader?

我有一个Yaml加载器,为一个"配置文件"加载额外的配置项(其中一个应用程序可以使用不同的配置文件,例如同一站点的不同本地版本)。

我的加载器非常简单:

# YamlProfileLoader.php
use Symfony'Component'Config'Loader'FileLoader;
use Symfony'Component'Yaml'Yaml;
class YamlProfileLoader extends FileLoader
{
    public function load($resource, $type = null)
    {
        $configValues = Yaml::parse($resource);
        return $configValues;
    }
    public function supports($resource, $type = null)
    {
        return is_string($resource) && 'yml' === pathinfo(
            $resource,
            PATHINFO_EXTENSION
        );
    }
}

加载器大致是这样使用的(简化了一点,因为也有缓存):

$loaderResolver = new LoaderResolver(array(new YamlProfileLoader($locator)));
$delegatingLoader = new DelegatingLoader($loaderResolver);
foreach ($yamlProfileFiles as $yamlProfileFile) {
    $profileName = basename($yamlProfileFile, '.yml');
    $profiles[$profileName] = $delegatingLoader->load($yamlProfileFile);
}

解析的Yaml文件也是如此:

# profiles/germany.yml
locale: de_DE
hostname: %profiles.germany.host_name%

目前,结果数组实际上包含'hostname'数组键的'%profiles.germany.host_name%'

那么,我如何解析%参数以获得实际的参数值呢?

我一直在浏览Symfony 2的代码和文档(以及这个SO问题),但找不到框架本身在哪里完成的。我可能会编写自己的参数解析器-从内核中获取参数,搜索%foo%字符串并查找/替换…但如果有一个组件准备使用,我更喜欢使用这个。

给出更多的背景,为什么我不能把它包含在主配置中。我希望能够加载app/config/profiles/*.yml,其中*是配置文件名称,我使用自己的加载器来完成此操作。如果有一种方法可以通配符导入配置文件,那么这可能也适用于我。

注意:目前使用2.4,但如果有帮助,准备升级到2.5。

我一直在浏览Symfony 2的代码和文档(以及这个SO问题),但找不到框架本身在哪里完成的。

Symfony的依赖注入组件在优化阶段使用编译器传递来解析参数引用。

编译器从它的PassConfig实例中获取注册的编译器传递。这个类默认配置了几个编译器传递,其中包括ResolveParameterPlaceHoldersPass。

在容器编译过程中,ResolveParameterPlaceHoldersPass使用容器的ParameterBag来解析包含%parameters%的字符串。然后,编译器传递将解析后的值设置回容器中。

那么,我如何解析%参数以获得实际的参数值呢?

您需要访问您的ProfileLoader(或任何您认为合适的地方)中的容器。使用容器,您可以递归地遍历已解析的yaml配置,并将值传递给容器的参数包,以便通过resolveValue()方法进行解析。


在我看来,也许更简洁的方法是在你的bundle配置中实现它。这样,您的配置将根据已定义的结构进行验证,从而可以及早发现配置错误。有关更多信息,请参阅有关bundle配置的文档(该链接适用于v2.7,但希望也适用于您的版本)。

我知道这是一个老问题,但我已经花了相当长的时间为我自己的项目弄清楚这个问题,所以我把答案贴在这里供将来参考。

我尝试了很多选项来将%parameter%解析为parameters。我知道,但一点也不走运。我所能想到的就是解析%参数%并从容器中获取它,还没有创新。

另一方面,我没有足够的信息来了解你的环境,但我只是想到了另一个想法。如果在参数中声明概要文件,这将非常方便。Yml文件,并通过容器将其作为数组加载到控制器或服务中。

app/config/parameters.yml

parameters:
    profiles:
        germany:
            locale: de_DE
            host_name: http://de.example.com
        uk:
            locale: en_EN
            host_name: http://uk.example.com
        turkey:
            locale: tr_TR
            host_name: http://tr.example.com 

你可以把你所有的配置文件作为一个数组放在你的控制器中。

<?php
namespace Acme'DemoBundle'Controller;
use Symfony'Bundle'FrameworkBundle'Controller'Controller;
class DefaultController extends Controller
{
    public function indexAction()
    {

        $profiles = $this->container->getParameter('profiles');
        var_dump($profiles);
        return $this->render('AcmeDemoBundle:Default:index.html.twig');
    }
}

使用这种方法

    你不需要编写自定义的YamlLoader
  • 您不必担心将参数导入到其他yml文件
  • 你可以把你的配置文件作为一个数组,只要你有$container在你的手
  • 你不需要逐个加载/缓存配置文件
  • 你不需要找到一个通配符文件加载解决方案

如果我对你的问题理解正确,这个方法可以帮助你。