按键查找YAML并更改值

时间:2016-02-23 13:14:54

标签: 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"]=>
  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'],然后将file_put_contents更改为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;
    }

这将返回任何节点,但它需要一个按键深度的确切顺序的数组。

我最初在想,如果我可以像在Container中那样创建一个ParameterBag。问题是我似乎无法从关联数组中找到它的位置,例如key-> value(例如,security.firewalls.main.pattern及其值)。如果我尝试从数组中创建一个ParameterBag,它不会修改该数组,该包包含完全相同的数组。我正在尝试找到解析数组的位置并将其转换为容器中的数组。

1 个答案:

答案 0 :(得分:1)

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

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

例如,您可以更改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'
             ),
        ),
    ),
):