Php 如何在symfony yaml配置组件中使用变量和导入文件
我在项目中使用symfony的config组件,我需要在yml配置文件的各个部分中使用相同的值 有人知道如何使用config组件重现symfony configuration.yml的行为吗 我想导入配置文件:Php 如何在symfony yaml配置组件中使用变量和导入文件,php,symfony,configuration,yaml,Php,Symfony,Configuration,Yaml,我在项目中使用symfony的config组件,我需要在yml配置文件的各个部分中使用相同的值 有人知道如何使用config组件重现symfony configuration.yml的行为吗 我想导入配置文件: imports: - { resource: otherfile.yml } 或声明变量: myvar: value othervar: %myvar% 好的,下面是一些未经测试的代码: <?php // parse yaml to an array $parser = n
imports:
- { resource: otherfile.yml }
或声明变量:
myvar: value
othervar: %myvar%
好的,下面是一些未经测试的代码:
<?php
// parse yaml to an array
$parser = new \Symfony\Component\Yaml\Parser();
$configs = $parser->parse(\file_get_contents('config.yml'));
// your config tree
$configuration = new Configuration();
// processor reading the config from the array according to the Configuration NodeTree
$processor = new Processor();
$result = $processor->processConfiguration($configuration, $configs);
// you can be 100% sure, that your $result array has the attributes you set in Configuration
处理器应该为您验证配置并引发异常。但是您也可以直接解析YAML并访问数组好的,下面是一些未经测试的代码:
<?php
// parse yaml to an array
$parser = new \Symfony\Component\Yaml\Parser();
$configs = $parser->parse(\file_get_contents('config.yml'));
// your config tree
$configuration = new Configuration();
// processor reading the config from the array according to the Configuration NodeTree
$processor = new Processor();
$result = $processor->processConfiguration($configuration, $configs);
// you can be 100% sure, that your $result array has the attributes you set in Configuration
处理器应该为您验证配置并引发异常。但是您也可以只解析YAML并直接访问阵列Symfony配置组件没有内置此功能。定义和解析配置文件中的导入和参数是DependencyInjection组件的一部分,即其文件加载程序类Symfony\component\DependencyInjection\Loader\FileLoader 如果不想将整个DependencyInjection组件添加为依赖项,那么最好的方法是简单地扩展配置组件自己的FileLoader类,重写load方法,读入配置,查找imports子元素,并在其中引用的文件路径上调用$this->import。 然后读取parameters键下的所有内容,迭代所有配置键,并用它们的值替换以前找到的任何参数 例如:
public function load($resource, $type = null)
{
// ...
// Load your config data as usual. It's assumed that
// the configuration is now a multidimensional array
// named $content
// Load the imports:
if (isset($content['imports'])) {
foreach ($content['imports'] as $import) {
$extraContent = $this->import($import['resource']);
$content = array_replace_recursive($extraContent, $content);
}
}
// Store the parameters:
if (isset($content['parameters'])) {
foreach ($content['parameters'] as $param) {
foreach ($param as $key => $value) {
$this->_parameters[$key] = $value;
}
}
}
// iterate over all configuration keys and substitute
// placeholders with parameter values:
array_walk_recursive(
$content,
function(&$val, $key) {
$matches = null;
preg_match('/\%(.*?)\%/', $val, $matches);
$param = isset($matches[1]) ? $matches[1] : false;
if ($param) {
if (isset($this->_parameters[$param])) {
$val = str_replace("%$param%", $this->_parameters[$param], $val);
}
}
}
);
// And you're done. From here on, proceed as usual
// (like, validate content against a ConfigurationInterface
// implementation
// ...
}
请注意:示例代码非常简短,不包含错误检查,也没有以这种简短的形式进行过测试——但它确实包含了所有必要的步骤,我希望它能为您指明正确的方向
还建议查看Symfony\Component\DependencyInjection\Loader\FileLoader类,看看它是如何完成的,忽略所有资源注册内容。Symfony配置组件没有内置此功能。定义和解析配置文件中的导入和参数是DependencyInjection组件的一部分,即其文件加载程序类Symfony\component\DependencyInjection\Loader\FileLoader 如果不想将整个DependencyInjection组件添加为依赖项,那么最好的方法是简单地扩展配置组件自己的FileLoader类,重写load方法,读入配置,查找imports子元素,并在其中引用的文件路径上调用$this->import。 然后读取parameters键下的所有内容,迭代所有配置键,并用它们的值替换以前找到的任何参数 例如:
public function load($resource, $type = null)
{
// ...
// Load your config data as usual. It's assumed that
// the configuration is now a multidimensional array
// named $content
// Load the imports:
if (isset($content['imports'])) {
foreach ($content['imports'] as $import) {
$extraContent = $this->import($import['resource']);
$content = array_replace_recursive($extraContent, $content);
}
}
// Store the parameters:
if (isset($content['parameters'])) {
foreach ($content['parameters'] as $param) {
foreach ($param as $key => $value) {
$this->_parameters[$key] = $value;
}
}
}
// iterate over all configuration keys and substitute
// placeholders with parameter values:
array_walk_recursive(
$content,
function(&$val, $key) {
$matches = null;
preg_match('/\%(.*?)\%/', $val, $matches);
$param = isset($matches[1]) ? $matches[1] : false;
if ($param) {
if (isset($this->_parameters[$param])) {
$val = str_replace("%$param%", $this->_parameters[$param], $val);
}
}
}
);
// And you're done. From here on, proceed as usual
// (like, validate content against a ConfigurationInterface
// implementation
// ...
}
请注意:示例代码非常简短,不包含错误检查,也没有以这种简短的形式进行过测试——但它确实包含了所有必要的步骤,我希望它能为您指明正确的方向
还建议查看Symfony\Component\DependencyInjection\Loader\FileLoader类,看看它是如何完成的,忽略所有资源注册的内容。一点Markus Wolff代码:
class FileLoader extends \Symfony\Component\Config\Loader\FileLoader
{
private $_parameters;
public function addParameter($k, $v)
{
$this->_parameters[$k] = $v;
}
public function load($resource, $type = null)
{
$resource = $this->getLocator()->locate($resource, null, true);
$content = \Symfony\Component\Yaml\Yaml::parse(file_get_contents($resource));
if (isset($content['imports'])) {
foreach ($content['imports'] as $import) {
$extraContent = $this->import($import['resource']);
$content = array_replace_recursive($extraContent, $content);
}
}
if (isset($content['parameters'])) {
foreach ($content['parameters'] as $key => $value) {
$this->_parameters[$key] = $value;
}
}
array_walk_recursive(
$content,
function (&$val) {
$matches = null;
preg_match_all('/\%(.*?)\%/', $val, $matches, PREG_SET_ORDER, 0);
if ($matches) {
foreach ($matches as $match) {
if ($param = isset($match[1]) ? $match[1] : false) {
if (isset($this->_parameters[$param])) {
$val = str_replace("%$param%", $this->_parameters[$param], $val);
}
}
}
}
}
);
return $content;
}
public function supports($resource, $type = null)
{
return is_string($resource) && 'yml' === pathinfo($resource, PATHINFO_EXTENSION);
}
}
对Markus Wolff代码的一点修改:
class FileLoader extends \Symfony\Component\Config\Loader\FileLoader
{
private $_parameters;
public function addParameter($k, $v)
{
$this->_parameters[$k] = $v;
}
public function load($resource, $type = null)
{
$resource = $this->getLocator()->locate($resource, null, true);
$content = \Symfony\Component\Yaml\Yaml::parse(file_get_contents($resource));
if (isset($content['imports'])) {
foreach ($content['imports'] as $import) {
$extraContent = $this->import($import['resource']);
$content = array_replace_recursive($extraContent, $content);
}
}
if (isset($content['parameters'])) {
foreach ($content['parameters'] as $key => $value) {
$this->_parameters[$key] = $value;
}
}
array_walk_recursive(
$content,
function (&$val) {
$matches = null;
preg_match_all('/\%(.*?)\%/', $val, $matches, PREG_SET_ORDER, 0);
if ($matches) {
foreach ($matches as $match) {
if ($param = isset($match[1]) ? $match[1] : false) {
if (isset($this->_parameters[$param])) {
$val = str_replace("%$param%", $this->_parameters[$param], $val);
}
}
}
}
}
);
return $content;
}
public function supports($resource, $type = null)
{
return is_string($resource) && 'yml' === pathinfo($resource, PATHINFO_EXTENSION);
}
}
复制对你意味着什么?如果要重用标量值,可以使用参数。如果你想重用一组设置,只需为它创建一个配置,让symfony解析它并将它交给一个带有一些getter的服务。我只使用symfony的config和yaml组件,而不是整个框架。因此,我想知道如何在加载symfony配置文件时重现symfony内核的行为。这不会发生在内核本身,而是在每个Bundle的DependencyInjection文件夹中,*Extension.php加载生成NodeTree.ok的配置对象,那么,有没有一个symfony组件可以在symfony项目之外允许这种良好的行为呢?复制对您意味着什么?如果要重用标量值,可以使用参数。如果你想重用一组设置,只需为它创建一个配置,让symfony解析它并将它交给一个带有一些getter的服务。我只使用symfony的config和yaml组件,而不是整个框架。因此,我想知道如何在加载symfony配置文件时重现symfony内核的行为。这不会发生在内核本身,而是在每个Bundle的DependencyInjection文件夹中,*Extension.php加载生成NodeTree.ok的配置对象,那么,有没有一个symfony组件可以在symfony项目之外允许这种良好的行为呢?如果知道这些类使用什么use语句会很好,如果知道这些类使用什么use语句会很好