【问题标题】:'Undefined' Notice while populating arrays'未定义' 填充数组时的注意事项
【发布时间】:2009-10-12 10:08:57
【问题描述】:

当使用来自 SimpleXML 调用的数据填充数组时,PHP 会抛出它认为是“未定义”键的异常,但是,输出实际上是正确的。

$doc = new SimpleXmlElement($http_result, LIBXML_NOCDATA);

$result = array();

$x = 0;

foreach($doc->users->user as $item) {
    $result['user'][$x]['id'] .= $item->id;
    $result['user'][$x]['name'] .= $item->name;
    $result['user'][$x]['email'] .= $item->email;
    $x++;
}

print json_encode($result);

这实际上输出了我所期望的,即{"user":[{"id":"4843977","name":"Test New User","email":"test@newuser.com"}]}

但是,也存在以下错误,我不完全确定原因 - 这在 5.2.6 中没有出现,但在 5.2.10 中出现

Notice: Undefined index: user in /var/vhosts/sys-dev/docs/file.php on line 36

Notice: Undefined offset: 0 in /var/vhosts/sys-dev/docs/file.php on line 36

Notice: Undefined index: id in /var/vhosts/sys-dev/docs/file.php on line 36

Notice: Undefined index: name in /var/vhosts/sys-dev/docs/file.php on line 37

Notice: Undefined index: email in /var/vhosts/sys-dev/docs/file.php on line 38

Notice: Undefined offset: 1 in /var/vhosts/sys-dev/docs/file.php on line 36

Notice: Undefined index: id in /var/vhosts/sys-dev/docs/file.php on line 36

Notice: Undefined index: name in /var/vhosts/sys-dev/docs/file.php on line 37

Notice: Undefined index: email in /var/vhosts/sys-dev/docs/file.php on line 38

Notice: Undefined offset: 2 in /var/vhosts/sys-dev/docs/file.php on line 36

Notice: Undefined index: id in /var/vhosts/sys-dev/docs/file.php on line 36

Notice: Undefined index: name in /var/vhosts/sys-dev/docs/file.php on line 37

Notice: Undefined index: email in /var/vhosts/sys-dev/docs/file.php on line 38

【问题讨论】:

    标签: php arrays


    【解决方案1】:

    我认为您必须将行中的“.=”更改为“=”:

    $result['user'][$x]['id'] = $item->id;
    $result['user'][$x]['name'] = $item->name;
    $result['user'][$x]['email'] = $item->email;
    

    【讨论】:

    • 这会消除大部分错误,但不会消除Notice: Undefined offset: 1 in /var/vhosts/sys-dev/docs/file.php on line 36
    • 也许在循环中尝试(不带 $X): $result['user'][] = array( 'id' => $item->id, 'name' => $item- >name, 'email' => $item->email );
    • 这最终输出了可用的{"user":[{"id":{"0":"4843977"},"name":{"0":"Test New User"},"email":{"0":"test@newuser.com"}}]}。虽然我可以看到并理解为什么 .= 可能不应该被使用,但这是我可以获得可读 JSON 输出的唯一方法。
    • ".=" 或 "=" 不读取 JSON 输出,它只是将值分配给左侧的 var。现在您还没有 $result['user'][$x]['id'] 索引然后必须使用“=”创建它。
    【解决方案2】:

    您没有定义什么是 $result['user'] 和 $result['user'][$x]。 您需要将它们实例化为数组,这样您就不会收到该错误。

    $result['user'] = array();
    foreach($doc->users->user as $item) {
        $result['user'][$x] = array();
        $x++;
    }
    

    对于字段中未定义的索引,问题类似。当变量尚不存在时,您使用“.=”。所以你应该先用一个空字符串来实例化它。

    $result['user'][$x]['name'] = '';
    

    【讨论】:

    • 数组的初始化不是必须的。甚至多维属性在第一次填充的那一刻就被初始化了
    【解决方案3】:

    需要先初始化$result数组:

    $result = array('user' => array());
    

    由于您使用的是字符串连接和赋值运算符.=,这也适用于$result['user'][$x] 数组:

    foreach($doc->users->user as $item) {
        $result['user'][$x] = array(
            'id'    => null,
            'name'  => null,
            'email' => null
        );
        $result['user'][$x]['id'] .= $item->id;
        $result['user'][$x]['name'] .= $item->name;
        $result['user'][$x]['email'] .= $item->email;
        $x++;
    }
    

    但这不是必需的,因为你也可以这样写:

    $result = array('user' => array());
    foreach($doc->users->user as $item) {
        $result['user'][] = array(
            'id'    => $item->id,
            'name'  => $item->name,
            'email' => $item->email
        );
    }
    

    编辑    由于我们详细说明了$item 的属性也是SimpleXMLElement 对象,因此需要$item->attr[0] 来处理字符串值本身。因此:

    $result = array('user' => array());
    foreach($doc->users->user as $item) {
        $result['user'][] = array(
            'id'    => $item->id[0],
            'name'  => $item->name[0],
            'email' => $item->email[0]
        );
    }
    

    【讨论】:

    • 不知道为什么它被否决了。无论如何,这个解决方案有效,但产生的结果与迄今为止所有其他答案相同:{"user":[{"id":{"0":"4843977"},"name":{"0":"Test New User"},"email":{"0":"test@newuser.com"}}]} 这不是真正有效的 JSON 输出
    • @jakeisonline:像$item->id 这样的项目属性可能不是字符串,而是其他一些对象。所以试试$item->id[0]
    • @gumbo:你说得对,它将它们添加为 SimpleXMLElement 对象。使用 $item->id[0] 引用它似乎没有什么区别,因为当您的 print_r 数组时它仍然显示为[id] => SimpleXMLElement Object ( [0] => 4802022 ),这意味着正在将另一个数组添加到 JSON 输出(或者,实际上,任何输出)
    • @gumbo:感谢您修改您的答案,非常感谢。然而,这仍然输出奇数数据。例如:Array ( [user] => Array ( [0] => Array ( [id] => SimpleXMLElement Object ( [0] => 4802022 ) [name] => SimpleXMLElement Object ( [0] => Dropbox Test User..... 我不知道为什么它转储对象引用而不是字符串/值。
    • @jakeisonline:您是否更改了将$item->attr 替换为$item->attr[0] 的代码?
    【解决方案4】:

    它发生了,因为您不只是设置数组值,而是连接到当前值:

    $result['user'][$x]['id'] .= $item->id;
    

    这一行的意思是“取$result['user'][$x]['id'] 的当前值并将$item->id 添加到它”。然后抛出通知,因为当前值还不存在。

    修改代码

    $result['user'][$x]['id'] = $item->id;
    

    你应该是安全的。不知道为什么 5.2.6 没有抛出错误,也许你应该检查 php.ini 中的 error_reporting 设置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-17
      相关资源
      最近更新 更多