我有一个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 :(得分:1)
我一直在浏览Symfony 2代码和文档(和这个问题,并且无法在框架内找到这样做的地方。
Symfony的依赖注入组件在优化阶段使用编译器传递来解析参数引用。
Compiler从其PassConfig实例获取已注册的编译器传递。此类配置a few compiler passes by default,其中包含ResolveParameterPlaceHoldersPass。
在容器编译期间,ResolveParameterPlaceHoldersPass
使用包含%parameters%
的容器的ParameterBag到resolve 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');
}
}
采用这种方法
如果我的问题正确,这种方法可以帮到你。