2014-07-10 21 views
7

我有一个Yaml加载程序,它为“配置文件”(其中一个应用程序可以使用不同配置文件,例如用于同一站点的不同本地版本)加载其他配置项。Symfony 2 - 如何在我自己的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。

回答

0

我尝试了很多选项来将%parameter%解析为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
  • 您不必担心输入参数到其他阳明文件就
  • 你可以有你配置文件作为数组在任何时候您手中都有$容器
  • 您不必一个一个地加载/缓存配置文件
  • 你不必找到通配符文件加载解决方案

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

1

我一直拖网通过的Symfony 2的代码和文档(这SO问题,找不到在哪里,这是框架本身内完成。

的Symfony的依赖注入组件使用的编译器通过在优化阶段,以解决参数引用。

Compiler获得注册的编译器从PassConfig例如通过。该类配置a few compiler passes by default,其中包括ResolveParameterPlaceHoldersPass

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

那么,我该如何解析%参数来获取实际的参数值呢?

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


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

我意识到这是一个古老的问题,但我花了很长一段时间为我自己的项目弄清楚这一点,所以我在这里发布答案供将来参考。

相关问题