PHP:从平面标量值填充嵌套数组

时间:2010-06-24 22:00:38

标签: php arrays nested nested-forms

问题

我有一个嵌套的PHP数组,我需要从平面标量填充 值。问题是我不能提前知道结构是什么 嵌套的PHP数组将在我收到填写请求之前 平坦的标量值。

示例

// example where we populate the array using standard PHP
$person['contact_info']['fname']  = 'Attilla';
$person['contact_info']['lname']  = 'Hun';
$person['contact_info']['middle'] = 'The';    
$person['hobbies'][0]             = 'Looting';
$person['hobbies'][1]             = 'Pillaging';

// example where we populate the array from flat scalar values
// (these are obtained from the user via name-value pairs)

// how can I correctly populate $person from this??
print($_GET['contact_info.fname']);   // 'Smokey';
print($_GET['contact_info.middle']);  // 'The';
print($_GET['contact_info.lname']);   // 'Bear';

// how can I correctly populate $person from this??
print($_GET['contact_info.fname']);   // 'Jabba';
print($_GET['contact_info.middle']);  // 'The';
print($_GET['contact_info.lname']);   // 'Hutt';

// How can I use these three flat scalars 
// to populate the correct slots in the nested array?

// example where we populate the array using standard PHP $person['contact_info']['fname'] = 'Attilla'; $person['contact_info']['lname'] = 'Hun'; $person['contact_info']['middle'] = 'The'; $person['hobbies'][0] = 'Looting'; $person['hobbies'][1] = 'Pillaging'; // example where we populate the array from flat scalar values // (these are obtained from the user via name-value pairs) // how can I correctly populate $person from this?? print($_GET['contact_info.fname']); // 'Smokey'; print($_GET['contact_info.middle']); // 'The'; print($_GET['contact_info.lname']); // 'Bear'; // how can I correctly populate $person from this?? print($_GET['contact_info.fname']); // 'Jabba'; print($_GET['contact_info.middle']); // 'The'; print($_GET['contact_info.lname']); // 'Hutt'; // How can I use these three flat scalars // to populate the correct slots in the nested array?

问题

我知道我不能成为第一个需要从平面名称 - 值对转换为嵌套PHP数组(或任何编程语言的嵌套数组)的人。将这些平面标量名称 - 值对转换为适当的PHP嵌套数组的既定方法(如果有的话)是什么?

只是为了重新迭代,我不能提前知道填充数组的名称 - 值对是什么,这是我在这里处理的一个约束。

更新

我无法知道这些值(或者,如果您愿意,可以通过标量值表示填充的数组键)是我正在处理的特定问题空间的约束。这不是关于基本PHP数组语法的问题。

2 个答案:

答案 0 :(得分:0)

我不确定你的意思是说你不能提前知道名字 - 值对会是什么。

参考您的示例,这将起作用:

<?php

$person['contact_info']['fname']  = $_GET['contact_info.fname'];
$person['contact_info']['lname']  = $_GET['contact_info.middle'];
$person['contact_info']['middle'] = $_GET['contact_info.lname']);    

?>

事先不知道是给定的 - 这就是用户输入的方式。

您必须事先知道。如果没有此信息,您就无法了解如何将$_GET中的值映射到$person中的值。

如果您事先不知道密钥,则无法解决此问题。如果您事先不知道密钥,则软件设计存在严重缺陷。

答案 1 :(得分:0)

注意:下面的我的PHP代码是黑客,而是执行此操作。有人之前发布了更好的解决方案,但是帖子现在已经消失了。简而言之,您已经可以将表单中的值数组提交给PHP:

<form ...>
<input type="text" name="contact_info[fname]">
<input type="text" name="contact_info[lname]">
<input type="text" name="contact_info[middle]">
</form>

name属性中的方括号完全按照您的想法执行。提交时,$_POST['contact_info']将是一个包含三个键的数组fnamelnamemiddle

如果可能,您应该使用此方法而不是我在下面编写的代码。它更干净,更好,更易于维护,它应该是这样做的。


这是一个有趣的挑战。我们将使用PHP有趣的方式来参考我们的优势。鉴于:

  • $ input是一个仅包含$ person
  • 的键/值对的数组
  • 句点始终是分隔符
  • 您永远不会遇到同时具有数组和非数组值的键,即永远不会同时存在'contact_info'和'contact_info.foo'

然后这个功能可能是你的起点。

function nifty_splitty_magicky_goodness($input) {
// Start out with an empty array.
    $person = array();
    foreach($input as $k => $v) {
    // This turns 'a.b' into array('a', 'b')
        $key_parts = explode('.', $k);
    // Here's the magic.  PHP references aren't to values, but to
    // the variables that contain the values.  This lets us point at
    // array keys without a problem.  Sometimes this gets in the way...
        $ref = &$person;
        foreach($key_parts as $part) {
        // If we didn't already turn the thing we're refering to into an array, do so.
            if(!is_array($ref))
                $ref = array();
        // If the key doesn't exist in our reference, create it as an empty array
            if(!array_key_exists($part, $ref))
                $ref[$part] = array();
        // Reset the reference to our new array.
            $ref = &$ref[$part];
        }
    // Now that we're pointing deep into the nested array, we can
    // set the inner-most value to what it should be.
        $ref = $v;
    }
    return $person;
}

// Some test data.    
$input = array(
    'a.b' => 1,
    'a.c' => 2,
    'a.d.e' => 3,
    'f' => 4,
    'g.h' => 5
);
// Run it!
var_export(nifty_splitty_magicky_goodness($input));
// Should produce:
array (
  'a' => 
  array (
    'b' => 1,
    'c' => 2,
    'd' => 
    array (
      'e' => 3,
    ),
  ),
  'f' => 4,
  'g' => 
  array (
    'h' => 5,
  ),

再次,这是一个黑客。您应该使用PHP表单处理来为您处理。