PHP - 如何修改深度嵌套的关联数组?

问题描述 投票:0回答:2

我在 PHP 中构建深度嵌套关联数组时遇到了麻烦。从我在这里和那里看到的问题/答案中,我认为我应该使用参考资料,但我只是不知道该怎么做。

我正在使用 PHP 5.3

我正在解析一个看起来像 JSON 的文件。它包含用大括号括起来的嵌套“部分”,我想使用嵌套关联数组构建文件的树表示。

我从根部分和“当前部分”变量开始:

$rootSection = array();
$currentSection = $rootSection;
$sections = array();

当我进入新部分('{')时,我会这样做:

$currentSection[$newSectionName] = array();
array_push($sections, $currentSection);
$currentSection = $currentSection[$newSectionName];

我使用

$sections
变量将一个节 ('}') 弹出到其父节中:

$currentSection = array_pop($sections);

最后,当我想向我的部分添加属性时,我基本上会这样做:

$currentSection[$name] = $value;

我已经删除了所有使用上述代码中的引用的尝试,因为到目前为止没有任何效果...... 我不妨说我习惯了 Javascript,其中引用是默认的......

但是 PHP 显然不是这样的? 我已将变量转储到解析代码中,可以看到所有属性都正确添加到同一个数组中,但

rootSection
数组或推入
$sections
的数组不会进行相同更新。

我几个小时以来一直在寻找一种方法来做到这一点,但我真的不明白...... 因此,请分享您可能对我有的任何帮助/指示!

更新:解决方案

感谢 chrislondon,我再次尝试使用

=&
,并设法使其工作。

初始化代码:

$rootSection = array();
$currentSection =& $rootSection;
$sections = array();

新部分('{'):

$currentSection[$newSectionName] = array();
$sections[] =& $currentSection;
$currentSection =& $currentSection[$newSectionName];

退出节('}'):

$currentSection =& $sections[count($sections) - 1];
array_pop($sections);

请注意,从 PHP 5.3 左右开始,类似

array_push($a, &$b);
的操作已被弃用并会触发警告。
$b =& array_pop($a)
也是不允许的;这就是为什么我使用
[]=
/
[]
运算符在我的
$sections
数组中推送/“弹出”。

我最初遇到的问题实际上是对我的部分堆栈的推送/弹出,我无法维护对数组的引用并且不断获取副本。

感谢您的帮助:)

php multidimensional-array reference
2个回答
1
投票

如果您想通过引用传递某些内容,请使用

=&
,如下所示:

$rootSection = array();
$currentSection =& $rootSection;

$currentSection['foo'] = 'bar';

print_r($rootSection);
// Outputs: Array ( [foo] => bar )

我也见过这样的语法

$currentSection = &$rootSection;
,但它们在功能上是相同的。


0
投票

一种更新嵌套关联数组的方法:对于给定的键值对,使用新的k-v对覆盖原来的,并在需要时插入新的k-v对。

例如1

use Illuminate\Support\Arr;

$data = [
  'feature_a1_enabled' => true,
  'feature_a2_enabled' => true,
  'feature_a2' => [
    'feature_a21_enabled' => true,
    'feature_a22_enabled' => true,
    'feature_a23_enabled' => true,
    'feature_a23' => [
      'feature_a231_enabled' => true,
      'feature_a232_enabled' => true,
    ],
  ],
  'feature_a3_enabled' => true,
];

$updates = [
  'feature_a2' => [
    'feature_a22_enabled' => false,
    'feature_a23' => [
      'feature_a233_enabled' => false,
    ],
  ],
  'feature_a3_enabled' => false,
  'feature_a4_enabled' => false,
];

$flattendUpdates = Arr::dot($updates);
foreach ($flattendUpdates as $k => $v) {
    Arr::set($data, $k, $v);
}
var_dump($data);

结果:

[
    "feature_a1_enabled" => true,
    "feature_a2_enabled" => true,
    "feature_a2" => [
      "feature_a21_enabled" => true,
      "feature_a22_enabled" => false,
      "feature_a23_enabled" => true,
      "feature_a23" => [
        "feature_a231_enabled" => true,
        "feature_a232_enabled" => true,
        "feature_a233_enabled" => false,
      ],
    ],
    "feature_a3_enabled" => false,
    "feature_a4_enabled" => false,
]

例如2

use Illuminate\Support\Arr;

$data = [];

$updates = [
  'feature_a2' => [
    'feature_a22_enabled' => false,
    'feature_a23' => [
      'feature_a233_enabled' => false,
    ],
  ],
  'feature_a3_enabled' => false,
  'feature_a4_enabled' => false,
];

$flattendUpdates = Arr::dot($updates);
foreach ($flattendUpdates as $k => $v) {
    Arr::set($data, $k, $v);
}

var_dump($data);

结果:

[
    "feature_a2" => [
      "feature_a22_enabled" => false,
      "feature_a23" => [
        "feature_a233_enabled" => false,
      ],
    ],
    "feature_a3_enabled" => false,
    "feature_a4_enabled" => false,
]

此方法可以更新或插入键,但不能删除键。

© www.soinside.com 2019 - 2024. All rights reserved.