【问题标题】:Dynamically creating/inserting into an associative array in PHP在 PHP 中动态创建/插入关联数组
【发布时间】:2011-01-27 16:34:31
【问题描述】:

我正在尝试在 PHP 中动态构建一个关联数组,但我的策略并没有完全正确。基本上,我想在数组结构的某个深度插入一个值,例如:

$array['first']['second']['third'] = $val;

现在,问题是,我不确定该深度是否可用,如果不可用,我想为每个级别创建键(和数组),最后在正确的级别插入值.

因为我在我的代码中做了很多这样的事情,我厌倦了做一大堆“array_key_exists”,所以我想做一个为我构建数组的函数,给定一个级别键列表.对此的良好策略的任何帮助表示赞赏。我敢肯定有一个非常简单的方法,我只是不明白......

【问题讨论】:

  • 你能展示一个你开始使用的数据集的例子吗?当你说“级别键”等 PS,欢迎来到 SO :-)
  • 您的数据是如何格式化以进行插入的,即键和 $val 存储在什么结构中?
  • @richsage:谢谢! @richsage 和@Andy:我将尝试使用示例结构更新帖子。基本上,我正在尝试创建一个结构来保存一个半复杂的表单,顶部有部分,然后是字段集、row-id:s、行标签文本和行值。

标签: php associative-array


【解决方案1】:

如果你这样做,php不会怪你

$array['first']['second']['third'] = $val;
print_r($array);

如果您不希望您的密钥被硬编码,这里有一个灵活的解决方案

/// locate or create element by $path and set its value to $value
/// $path is either an array of keys, or a delimited string
function array_set(&$a, $path, $value) {
    if(!is_array($path))
        $path = explode($path[0], substr($path, 1));
    $key = array_pop($path);
    foreach($path as $k) {
        if(!isset($a[$k]))
            $a[$k] = array();
        $a = &$a[$k];
    }
    $a[$key ? $key : count($a)] = $value;
}

// example:
$x = array();

array_set($x, "/foo/bar/baz", 123);
array_set($x, "/foo/bar/quux", 456);
array_set($x, array('foo', 'bah'), 789);

【讨论】:

  • 不,它没有,但我考虑使用未初始化的变量(如内部数组)错误的编码风格。我认为 PHP 会生成一个严格的 NOTICE。
  • @stereofrog:我认为通知是需要注意的,但同意了; “责备”也许有点强烈。
  • @stereofrog - 感谢一百万 - 这成功了。我已经开始了类似的事情,但无法掌握参考部分。现在我可以在下午剩下的时间里试着摸索它,而不是扯掉更多的头发。 :-)
  • 如果您知道数组键是好的(只是可能不存在),并且您设置的值是好的,您可以使用错误控制运算符(@ )。
【解决方案2】:

创建一个类似的函数:

function insert_into(&$array, array $keys, $value) {
     $last = array_pop($keys);       

     foreach($keys as $key) {
          if(!array_key_exists($key, $array) || 
              array_key_exists($key, $array) && !is_array($array[$key])) {
                  $array[$key] = array();

          }
          $array = &$array[$key];
     }
     $array[$last] = $value;
}

用法:

$a = array();
insert_into($a, array('a', 'b', 'c'), 1);
print_r($a);

输出:

Array
(
    [a] => Array
        (
            [b] => Array
                (
                    [c] => 1
                )

        )

)

【讨论】:

    【解决方案3】:

    这很棘手,您需要使用引用(或使用递归,但我 在这里选择参考):

    # Provide as many arguments as you like:
    # createNestedArray($array, 'key1', 'key2', etc.)
    function createNestedArray(&$array) {
        $arrayCopy = &$array;
        $args = func_get_args();
        array_shift($args);
        while (($key = array_shift($args)) !== false) {
            $arrayCopy[$key] = array();
            $arrayCopy = &$arrayCopy[$key];
        }
    }
    

    【讨论】:

      【解决方案4】:
      <?php
      
      function setElements(&$a, array $path = [], $values = [])
      {
      
          if (!is_array($path)) {
              $path = explode($path[0], substr($path, 1));
          }
      
              $path = "[ '" . join("' ][ '", $path) . "' ]";
              $code =<<<CODE
              if(!isset(\$a{$path})){
                  \$a{$path} = [];
              }
              return \$a{$path}[]  = \$values;
      CODE;
      
              return eval($code);
      }
      
      $a = [];
      setElements($a, [1,2], 'xxx');
      setElements($a, [1,2,3], 233);
      setElements($a, [1,2,4], 'AAA');
      setElements($a, [1,2,3,4], 555);
      print_r($a);
      

      输出

      Array
      (
          [1] => Array
              (
                  [2] => Array
                      (
                          [0] => xxx
                          [3] => Array
                              (
                                  [0] => 233
                                  [4] => Array
                                      (
                                          [0] => 555
                                      )
      
                              )
      
                          [4] => Array
                              (
                                  [0] => AAA
                              )
      
                      )
      
              )
      
      )
      

      你应该在这里查看http://sandbox.onlinephpfunctions.com/

      【讨论】:

      • 也许你可以解释一下这是做什么的。粘贴代码示例很好,但是关于它的含义的一些注释会很有用。
      猜你喜欢
      • 2011-07-28
      • 2014-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-25
      • 1970-01-01
      相关资源
      最近更新 更多