Symfony 2 - 如何在我自己的Yaml文件加载器中解析%parameter%?

时间:2014-07-10 11:52:04

标签: php symfony

我有一个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%

目前,生成的数组包含'%profiles.germany.host_name%'数组键的字面'hostname'

那么,如何解析%参数以获取实际参数值?

我一直在浏览Symfony 2代码和文档(以及this SO question并且无法在框架内找到这样做的地方。我可能会编写自己的参数解析器 - 获取来自内核的参数,搜索%foo%字符串和查找/替换...但是如果有一个组件准备好使用,我更喜欢使用它。

为了提供更多背景信息,为什么我不能将其包含在主config.yml中:我希望能够加载app/config/profiles/*.yml,其中*是个人资料名称,我正在使用自己的Loader来实现这一目标。如果有通配符导入配置文件的方法,那么这对我也有用。

注意:目前正在使用2.4但只是准备好升级到2.5,如果这有帮助。

2 个答案:

答案 0 :(得分:1)

  

我一直在浏览Symfony 2代码和文档(和这个问题,并且无法在框架内找到这样做的地方。

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

Compiler从其PassConfig实例获取已注册的编译器传递。此类配置a few compiler passes by default,其中包含ResolveParameterPlaceHoldersPass

在容器编译期间,ResolveParameterPlaceHoldersPass使用包含%parameters%的容器的ParameterBagresolve strings。然后,编译器传递将该已解析的值设置回容器中。

  

那么,如何解析%参数以获取实际参数值?

您需要访问ProfileLoader中的容器(或您认为合适的位置)。使用容器,您可以递归迭代已解析的yaml配置,并将值传递到容器的参数包,以通过resolveValue()方法解析。

在我看来,或许更简洁的方法是在捆绑配置中实现这一点。这样,您的配置将根据定义的结构进行验证,该结构可以及早捕获配置错误。有关详细信息,请参阅bundle configuration上的文档(该链接适用于v2.7,但希望也适用于您的版本)。

我意识到这是一个老问题,但我已经花了很长时间来解决这个问题,所以我在这里发布答案以供将来参考。

答案 1 :(得分:0)

我尝试了很多选项来将%参数%解析为parameters.yml,但根本没有运气。我能想到的只是解析%参数%并从容器中获取它,还没有创新。

另一方面,我没有足够的关于你的环境的信息来看大局,但我想出了另一个想法。如果在parameters.yml文件中声明配置文件并将其作为数组加载到控制器或服务中,则可以非常方便。

应用程序/配置/ 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,就可以将您的个人资料作为数组
  • 您不必逐个加载/缓存个人资料文件
  • 您不必查找通配符文件加载解决方案

如果我的问题正确,这种方法可以帮到你。