Symfony 按键查找YAML并更改值

Symfony 按键查找YAML并更改值,symfony,yaml,Symfony,Yaml,我想解析任何.yml文件的内容并修改任何键 让我们以security.yml文件为例,获取其内容并使用Yaml::parse,它将返回一个数组及其结构 $yml='/config/security.yml'; $path = $this->get('kernel')->getRootDir().$yml; $contents= Yaml::parse(file_get_contents($file)); 这个输出 array(1) { ["security"]=>

我想解析任何.yml文件的内容并修改任何键

让我们以security.yml文件为例,获取其内容并使用Yaml::parse,它将返回一个数组及其结构

$yml='/config/security.yml';    
$path = $this->get('kernel')->getRootDir().$yml;
$contents= Yaml::parse(file_get_contents($file));
这个输出

array(1) {
  ["security"]=>
  array(5) {
    ["encoders"]=>
    string(8) "Array(1)"
    ["role_hierarchy"]=>
    string(8) "Array(3)"
    ["providers"]=>
    string(8) "Array(2)"
    ["firewalls"]=>
    string(8) "Array(2)"
    ["access_control"]=>
    string(9) "Array(14)"
  }
}
到目前为止还不错。现在让我们假设我想更改
security.firewalls.main.pattern的值。我需要更改数组值
$contents['security']['firewalls']['main']['pattern']
,然后将内容放入yaml转储文件

我的问题是如何通过任何键动态地获取和设置参数值,而不是像上面那样硬编码。Yaml解析器无法通过其键获取值。我需要一种方法将
security.firewalls.main.pattern
以某种方式转换为数组键。显然,之后我会删除缓存

与此同时,我做了一些事情:

   $array = Yaml::parse(file_get_contents($file));  
   $keys=array("security","firewalls","main");
   $val = $this->parseYmlArray($array, $keys);

   public function parseYmlArray($array, $keys)
    {
        $newArr = $array;
        foreach ($keys as $key) {
            $newArr = $newArr[$key];
        }
        return $newArr;
    }
这将返回任意节点,但它需要一个按键深度的精确顺序排列的数组


起初我在想,我是否可以做一个像集装箱里的那个一样的参数包。问题是,我似乎找不到从深度关联数组到key->value(例如security.firewalls.main.pattern及其值)这样的数组的创建位置。如果我尝试从数组中创建一个ParameterBag,它不会修改该数组,该包包含完全相同的数组。我试图找到数组被解析并转换为容器中的数组的位置。

实际上,我没有看到任何直接更新配置值的替代方法

但是,您可以通过定义参数来实现这一点

例如,您可以更改
security.firewalls.main.pattern
,如下所示:

parameters:
    firewall_main_pattern: ^/yourpattern
    # ...

firewalls:
    # ...
    main:
        pattern: %firewall_main_pattern%
        # ...
然后,根据需要更新参数:

$this->container->setParameter('firewall_main_pattern', '^/yournewpattern');
希望这能解决你的问题

更新

在相同类型的
parseYmlArray
中,可以使用以下命令更改值:

function assignConfigurationValueByPath(&$array, $path, $value) {
    $keys = explode('.', $path);
    while ($key = array_shift($keys)) {
        $arr = &$arr[$key];
    }

    $arr = $value;
}

$array = Yaml::parse(file_get_contents($file));
assignConfigurationValueByPath($array, 'security.firewalls.main.pattern, 'new_value');
现在,
$array
更改为:

array(
    'security' => array(
        // ...
        'firewalls' => array(
             // ...
             'main' => array(
                 // ...
                 'pattern' => 'new_value'
             ),
        ),
    ),
):

事实并非如此。我正在寻找一种动态而不是手动更改它们的方法。我正在修改缓存后重建缓存。我如何理解您的问题,您当前正在解析YAML,手动更改值并重写整个配置文件,您正在寻找一种方法来更改参数,而无需硬编码YAML解析。这就是为什么我建议你用一种更干净的方式来做这件事。也许可以通过谈论避免缓存重建和动态更改而不是手动定义来精确回答您的问题。使用setParameter不会有帮助。实际使用firewall\u main\u模式的服务实际上被编译到缓存的容器定义文件中。在编译器过程之外没有实际的方法来修改它们。看看缓存目录。很多有趣的事情都在进行中。修改防火墙就是一个例子。其目的是修改任何.yml,而不是特别修改这个。编译器传递不允许动态修改。它们需要来自.yml文件。好的,现在清楚了,谢谢@GeorgeIrimiciuc如果您更新配置值(来自任何配置文件)时没有,则无法在同一请求中获取最新配置。请看一看属性访问器:可能值得一看,也许我可以重构上述函数。