CodeIgniter报Cannot access offset of type string on string错误解决
错误产生原因
报错Cannot access offset of type string on string的核心原因是代码中尝试对字符串类型的变量使用数组下标取值,结合给出的业务代码,共有3处高概率触发点:
- 第二层循环遍历
$report时,默认所有$value都是带data键的数组,但实际数据中存在$value本身为字符串的情况,执行$value['data']时直接触发报错。 - 执行
json_decode($value['data'], true)时没有做合法性校验:如果$value['data']不是标准JSON格式,解码会返回null或空字符串,后续直接遍历这个非数组类型的返回值时,循环拿到的$r是字符串类型,再执行$r['id']、$r['value']这类数组下标取值操作就会触发报错。 array_search查找商品ID时没有做结果校验:如果当前$r['id']在$commodities数组中不存在匹配项,array_search会返回false,直接将false作为索引读取$commodities[$key_array_commodity]['satuan']也会触发类型错误。
修复后可正常运行的代码
修复逻辑核心是增加每一步的类型合法性校验,遇到脏数据直接跳过,避免阻断整体流程:
foreach ($report_last_6_days as $day => $report): $mapping_reports[$day]['date'] = $day; // 校验$report是否为可遍历数组,非数组直接跳过 if (!is_array($report)) continue; foreach ($report as $key => $value): // 校验$value是否为数组、是否存在data字段 if (!is_array($value) || !isset($value['data'])) continue; $obj_data = json_decode($value['data'], true); // 校验JSON解码结果是否为数组,解码失败直接跳过 if (!is_array($obj_data) || json_last_error() !== JSON_ERROR_NONE) continue; foreach ($obj_data as $key_obj => $r): // 校验当前循环项是否为数组、必填字段是否存在 if (!is_array($r) || !isset($r['id'], $r['value'], $r['nama'])) continue; $key_array_commodity = array_search($r['id'], array_column($commodities, 'id')); // 没找到匹配商品时给默认单位,避免非法索引 $satuan = $key_array_commodity !== false ? $commodities[$key_array_commodity]['satuan'] : ''; $price = $r['value'] ? (int) $r['value'] : '-'; // 初始化prices数组,避免首次取值时不存在报错 if (!isset($mapping_reports[$day]['data'][$r['id']]['prices'])) { $mapping_reports[$day]['data'][$r['id']]['prices'] = []; } $mapping_reports[$day]['data'][$r['id']]['id'] = $r['id']; $mapping_reports[$day]['data'][$r['id']]['name'] = $r['nama']; $mapping_reports[$day]['data'][$r['id']]['satuan'] = $satuan; $mapping_reports[$day]['data'][$r['id']]['prices'][] = $price; $mapping_reports[$day]['data'][$r['id']]['geomean'] = geomean($mapping_reports[$day]['data'][$r['id']]['prices']); endforeach; endforeach; endforeach;
额外排查建议
如果加完校验还是有问题,可以在解码失败的分支里打印$value['data']的原始值,排查是哪条数据不是合法JSON格式,从数据源层面修复脏数据即可。
内容的提问来源于stack exchange,提问作者Anwr Rawk
相关产品推荐
相关产品推荐

