You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP访问数组元素提示Illegal string offset非法偏移报错排查

报错原因

这个警告的触发逻辑非常明确:你正在使用字符串键名Time/attr访问一个非数组的标量值(字符串、数字类型),PHP不支持以数组键的方式读取标量值,就会抛出Illegal string offset 'xxx'警告。
结合你给出的代码和补充现象,问题根源是XML转数组时的结构不统一,这是这类XML解析操作里最高发的坑:

  • 当某个Series节点下有2个及以上Obs子节点时,解析器会按你贴出的结构返回:Obs对应一个数字索引数组,每个元素是包含Time、attr键的关联数组,这部分遍历不会出问题
  • 当某个Series节点下只有1个Obs子节点时,解析器不会给Obs套一层数字索引的包装数组,直接把Obs本身的关联数组(含Time、attr键)赋值给$series['Obs']。这时候你遍历$series['Obs'],拿到的$obs_element就不是子数组,而是Time对应的标量值(比如年份数字、数值字符串)、attr对应的子数组,此时再用$obs_element['Time']访问标量,就会触发警告。

你提到的「直接用$series['Obs']['Time']能正常运行」的现象,刚好能印证这个原因——这种写法刚好命中了单Obs场景下的关联数组结构,所以能直接取到值。

修复方案

  1. 先确认结构:可以先在循环内临时打印$series['Obs']的内容,就能直观看到不同Series下Obs的结构差异
foreach($xmlArray['message:MessageGroup']['DataSet']['Series'] as $series_key => $series) {
    // 临时调试:打印Obs结构确认问题
    var_dump($series['Obs']);
}
  1. 遍历前统一Obs结构,把单条的关联数组包装成索引数组,保证遍历逻辑一致即可:
foreach($xmlArray['message:MessageGroup']['DataSet']['Series'] as $series_key => $series) {
    // 统一Obs为索引数组结构
    $obsList = isset($series['Obs']['Time']) ? [$series['Obs']] : $series['Obs'];
    foreach($obsList as $obs_element) {
        echo $obs_element["Time"];
        echo $obs_element["attr"]["value"];
    }   
}

小概率场景:部分XML转数组库会把节点的内置文本、全局属性存在特殊字符串键下(比如_value、@attributes),遍历到这类键对应的字符串值时也会触发相同警告,用上面的打印调试方法可以直接定位。

内容的提问来源于stack exchange,提问作者S.I.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 14:27:17