我在 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
数组中推送/“弹出”。
我最初遇到的问题实际上是对我的部分堆栈的推送/弹出,我无法维护对数组的引用并且不断获取副本。
感谢您的帮助:)
如果您想通过引用传递某些内容,请使用
=&
,如下所示:
$rootSection = array();
$currentSection =& $rootSection;
$currentSection['foo'] = 'bar';
print_r($rootSection);
// Outputs: Array ( [foo] => bar )
我也见过这样的语法
$currentSection = &$rootSection;
,但它们在功能上是相同的。
一种更新嵌套关联数组的方法:对于给定的键值对,使用新的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,
]
此方法可以更新或插入键,但不能删除键。