PHP在没有通知的情况下为多维数组添加新索引

时间:2015-03-18 21:19:23

标签: php arrays multidimensional-array

举个例子:

$data = array();
$data['a']['one'] = 'test';

由于$data['a']不存在,因此会发出通知。所以相反,我总是这样做:

$data = array();
$data['a'] = array();
$data['a']['one'] = 'test';

或者如果我在一个循环中,就像这样:

$data = array();
foreach ($items as $item) {
    if (!isset($data['a'])) {
        $data['a'] = array();
    }
    $data['a']['one'] = $item->getId();
}

这在代码中变得非常敏感并且凌乱。我知道我可以编写某种array_push替代函数来处理这个问题,但我想知道是否有办法用现有的PHP方法做到这一点。

7 个答案:

答案 0 :(得分:1)

您可能希望查看ArrayObject类,以下运行时没有错误或警告

<?php

error_reporting(E_ALL| E_NOTICE);
ini_set('display_errors', 1);

$ar = new ArrayObject();

$ar['foo']['bar'] = 1;
assert($ar['foo']['bar'] === 1);

结帐ideone

答案 1 :(得分:1)

首先在某处初始化整个阵列(所有键,子阵列等)是不切实际的。

这意味着记住并维护它 - 当您以前没有考虑过新数据时,您还必须将其添加到阵列初始化中。
(Urgh)

我至少会将var作为一个数组($data = array();)进行delcare,然后你就不需要is_array() - 在你做任何有用的事情之前,这是一个恼人的单行代码(两行包括闭合支撑..)。

但是,不需要您的检查 您的代码检查是否已设置阵列的子阵列,如果没有,则将其设置为阵列,然后将数据设置到其上。

这不是必需的,因为即使之前未设置某些子键/数组,您也可以在数组中设置数据。

例如,此代码(这是整个文件,所有代码都已运行赢得抛出错误,警告或通知:

$data['a']['one']['blah']['foo'] = 'test';

print_r($data);

echo $data['a']['one']['blah']['foo'];

以上输出:

Array ([a] => Array ( [one] => Array ( [blah] => Array ( [foo] => test ) ) ) )

test

以上代码将返回任何警告/通知/错误 另请注意,我甚至没有$data = array() (虽然你想,因为你可能使用foreach并且初始化否定了使用is_array的需要)。

那是error_reporting(-1);

TL; DR; - 答案

所以要回答你的问题,在你的代码中你可以这样做(并且不会收到任何错误/通知/警告):

$data = array();

// more data setting the array up  

foreach ($items as $item) {
    $data['a']['one'] = $item->getId();
}

答案 2 :(得分:0)

在分配期间创建数组:

$data=[];
$data['a'] = ['one' => 'test'];

或者一次性创建整个结构

$data = ['a'=>['one'=>'test']];

答案 3 :(得分:0)

我不相信有任何内置方法可以满足您的需求:PHP array functions

创建自己的函数可能是实现这一目标的最佳方法。或者,根据您的使用情况,您可以创建数据数组,以便单独添加到键a,如下所示:

$data = array();
$array_data = array();
foreach ($items as $key => $item) {
    $array_data[$key] = $item->getId(); // presuming your 'one' is a dynamic key  
}
$data['a'] = $array_data;

这是否比你的方法更好是我认为的问题。

答案 4 :(得分:0)

您可以通过添加@来绕过通知。您也可以禁用我根本不推荐的通知。

我认为有更好的方法来编写这样的代码:

$a['one'] = 'test';
$a['two'] = 'test';
$data['a'] = $a;

或:

$data['a'] = ['one'=>'test', 'two'=>'test']

或:

$data = ['a'=>['one'=>'test', 'two'=>'test']];

答案 5 :(得分:0)

当处理动态数据时,多人建议从一开始就将数组简单地创建为多维数组的方法通常不是一个选项。例如:

$orderItems = array();
foreach ($items as $item) {
    $oId = $order->getId();
    if (!isset($orderItems[$oId])) {
        $orderItems[$oId] = array();
    }

    $pId = $item->getPackageNumber();
    if (!isset($orderItems[$oId][$pId])) {
        $orderItems[$oId][$pId] = array('packages'=>array());
    }

    $orderItems[$oId][$pId][] = $item;
}

听起来我需要创建一个函数来为我做这个。我创建了这个递归函数,似乎可以完成这项工作:

function array_md_push(&$array, $new) {
    foreach ($new as $k => $v) {
        if (!isset($array[$k])) {
            $array[$k] = array();
        }

        if (!is_array($v)) {
            array_push($array[$k], $v);
        } else {
            array_md_push($array[$k], $v);
        }
    }
}

$test = array();
$this->array_md_push($test, array('a' => array('one' => 'test')));
$this->array_md_push($test, array('a' => array('one' => 'test two')));
$this->array_md_push($test, array('a' => array('two' => 'test three')));
$this->array_md_push($test, array('b' => array('one' => 'test four')));

这给了我这个:

array(2) {
  ["a"] => array(2) {
    ["one"] => array(2) {
      [0] => string(4) "test"
      [1] => string(8) "test two"
    }
    ["two"] => array(1) {
      [0] => string(10) "test three"
    }
  }
  ["b"] => array(1) {
    ["one"] => array(1) {
      [0] => string(9) "test four"
    }
  }
}

答案 6 :(得分:-1)

这很有效。您不需要设置为空数组

$ data ['a'] ['one'] ='test';