【问题标题】:PHP 5.4 Illegal String Offset ErrorPHP 5.4 非法字符串偏移错误
【发布时间】:2014-06-27 18:00:06
【问题描述】:

我正在使用 foreach 构造来查看从函数返回的数组。不幸的是,如果只有 1 个结果,则此函数返回不同的结构,而不是有超过 1 个结果。当有一个结果时,我得到以下信息:

array(3) {
  ["name"]=>
  string(5) "chris"
  ["admin"]=>
  string(5) "chris"
  ["time"]=>
  string(19) "2014/06/27 12:36:31"
}
string(34) "$1$9243ujf0i2j8ehdf24hdf9a8"

我正在尝试获取 ["name"] 值。如果我使用以下代码,我的变量有正确的数据,但我得到一个非法字符串偏移错误:

foreach($res[1]['result']['user']['entry'] as $user) {
  $s = $user['name'];
  echo $s;
}

如何正确获取数组["name"] 值?还是我必须在更高的层次上做一些不同的事情?当有一个条目时,我得到的原始数据如下:

array(2) {
  ["@attributes"]=>
  array(2) {
    ["status"]=>
    string(7) "success"
    ["code"]=>
    string(2) "19"
  }
  ["result"]=>
  array(2) {
    ["@attributes"]=>
    array(2) {
      ["total-count"]=>
      string(1) "1"
      ["count"]=>
      string(1) "1"
    }
    ["user"]=>
    array(2) {
      ["@attributes"]=>
      array(2) {
        ["admin"]=>
        string(5) "chris"
        ["time"]=>
        string(19) "2014/06/27 12:39:58"
      }
      ["entry"]=>
      array(2) {
        ["@attributes"]=>
        array(3) {
          ["name"]=>
          string(5) "chris"
          ["admin"]=>
          string(5) "chris"
          ["time"]=>
          string(19) "2014/06/27 12:36:31"
        }
        ["phash"]=>
        string(34) "$1$9243ujf0i2j8ehdf24hdf9a8"
      }
    }
  }
}

当有多个条目时如下:

array(2) {
  ["@attributes"]=>
  array(2) {
    ["status"]=>
    string(7) "success"
    ["code"]=>
    string(2) "19"
  }
  ["result"]=>
  array(2) {
    ["@attributes"]=>
    array(2) {
      ["total-count"]=>
      string(1) "1"
      ["count"]=>
      string(1) "1"
    }
    ["user"]=>
    array(2) {
      ["@attributes"]=>
      array(2) {
        ["admin"]=>
        string(5) "chris"
        ["time"]=>
        string(19) "2014/06/27 12:57:32"
      }
      ["entry"]=>
      array(2) {
        [0]=>
        array(2) {
          ["@attributes"]=>
          array(3) {
            ["name"]=>
            string(5) "chris"
            ["admin"]=>
            string(5) "chris"
            ["time"]=>
            string(19) "2014/06/27 12:36:31"
          }
          ["phash"]=>
          string(34) "$1$9243ujf0i2j8ehdf24hdf9a8"
        }
        [1]=>
        array(2) {
          ["@attributes"]=>
          array(3) {
            ["name"]=>
            string(4) "test"
            ["admin"]=>
            string(5) "chris"
            ["time"]=>
            string(19) "2014/06/27 12:57:32"
          }
          ["phash"]=>
          string(34) "$1$as9d8jf238r9jf89j9238jr"
        }
      }
    }
  }
}

注意 ["entry"] 之后的额外索引数组级别。基本上,我只想要 ["name"] 值的列表。

【问题讨论】:

  • 我很确定你想要foreach($res[1]['result']['user']['entry']['@attributes'] as $user)。它们都在该子数组中保存name 位。
  • 并非如此。再看结构,划分是在入口之后。
  • @Anthony:谢谢,但这行不通。当有多个条目时,那里有一个额外的数组级别:$res[1]['result']['user']['entry'][0]['@attributes']。当只有一个条目时,它只是 $res[1]['result']['user']['entry']['@attributes']。
  • 我完全错过了条目拆分为数组的位置。但是,如果您不将@attributes 添加到任一路径,则会出现非法偏移。数组从何而来?
  • @Anthony:请参阅下面我对 this.lau_ 的回答的评论。

标签: php


【解决方案1】:

根据结果数量返回不同结构的服务一开始就被破坏了。如果无法修复,您可以尝试在处理之前对数据进行规范化,如下所示:

if (!isset($res[1]['result']['user']['entry'][1]) {
    // Not an array, so change the structure to an array with one element:
    $res[1]['result']['user']['entry'] = array($res[1]['result']['user']['entry']);
}

// Now process the data as if the service is always returning an array

【讨论】:

  • 返回数据的源函数是通过执行 $xml = simplexml_load_string, $json = json_encode($xml) 然后 $ret_array = json_decode($json, true) 将一些 XML 转换为数组.不知道我是否可以解决这个问题,或者是否有更好的方法来做到这一点。无论如何,您的回答效果很好!谢谢。
  • 修改数据以适应代码一般来说不是一个好主意,但它会“工作”。
【解决方案2】:

您可以像这样规范化 entry 数组:

if(!isset($entries['result']['user']['entry'][0])) {
    $entry_list[] = $entries['result']['user']['entry'];
} else {
    $entry_list = $entries['result']['user']['entry'];
}

然后用foreach对新的$entry_list数组进行操作,不用担心。

【讨论】:

  • 谢谢!这导致了我认为最简单的代码。
  • 它看起来更简单,但它与@this.lau_的效果相同,只是额外分配给$entry_list
【解决方案3】:

您可以使用is_array

$test = $res[1]['result']['user']['entry'];
if (is_array($test)) {
    foreach($test as $user) {
        $s = $user['@attributes']['name'];
        echo $s;
    }
} else {
    $s = $test['@attributes']['name'];
    echo $s;
}

【讨论】:

  • 这似乎不起作用。 is_array($test) 无论是否有一个或多个条目,都会评估 true。我想我需要知道的是 $res[1]['result']['user']['entry'][0] 是否存在。
  • 使用你的建议,我得到了以下工作: $test = $res[1]['result']['user']['entry']; if (is_array($test[0])) { foreach($test as $user) { echo $user['@attributes']['name']; } } 其他 { 回声 $test['@attributes']['name']; }
  • 我只是错过了 ['@attributes'] 部分...但是如果您测试 $test[0] 而不是 $test,那么当它是单个值时会出现错误,因为$test[0] 将不存在。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多