【问题标题】:Flatten a PHP array展平 PHP 数组
【发布时间】:2011-02-11 17:47:19
【问题描述】:

假设我有一个包含这些字段的表单,但无法重命名:

<input type="text" name="foo[bar]" />
<input type="text" name="foo[baz]" />
<input type="text" name="foo[bat][faz]" />

提交后,PHP 将其转换为数组:

Array
(
    [foo] => Array
        (
            [bar] => foo bar
            [baz] => foo baz
            [bat] => Array
                (
                    [faz] => foo bat faz
                )

        )

)

有哪些方法可以将该数组转换或展平为数据结构,例如:

Array
(
    [foo[bar]] => foo bar
    [foo[baz]] => foo baz
    [foo[bat][faz]] => foo bat faz
)

【问题讨论】:

标签: php forms arrays


【解决方案1】:

可能是愚蠢的答案,但为什么不做呢

<input type="text" name="foobar" />
<input type="text" name="foobaz" />
<input type="text" name="foobatfaz" />

?

【讨论】:

  • 问题的第一句话:“假设我有一个包含这些字段的表单,并且无法重命名它们......”
【解决方案2】:

不是您问题的答案,而是extract 将获取一个数组并从中生成变量。例如;

$array = array
    (
        [foo] => foo bar
        [boo] => something else
    )
extract($array);

输出

$foo = 'foo bar';
$boo = 'something else';

关于如何处理相同的索引名称有几个选项,例如,覆盖现有值或在变量名称后附加前缀。

【讨论】:

  • extract 与用户输入一起使用总是不好的主意
【解决方案3】:

我想这就是你想要的

$ritit = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr));
$result = array();
foreach ($ritit as $leafValue) {
    $path = 'foo99';
    foreach (range(0, $ritit->getDepth()) as $depth) {
        $path .= sprintf('[%s]', $ritit->getSubIterator($depth)->key());
    }
    $result[$path] = $leafValue;
}

默认情况下,RecursiveIteratorIterator 只访问叶节点,因此外部 foreach 循环的每次迭代都有迭代器结构停止在您关心的值之一上。通过查看 RecursiveIteratorIterator 正在为我们创建和管理的迭代器(每个级别使用一个迭代器),我们找到了构建路径的关键。

【讨论】:

  • 太棒了,谢谢克里斯!我真的应该更多地了解 SPL
猜你喜欢
  • 2021-11-15
  • 2020-06-06
  • 1970-01-01
  • 1970-01-01
  • 2013-09-12
  • 2014-05-21
  • 1970-01-01
  • 2015-04-08
  • 2013-06-13
相关资源
最近更新 更多