PHP访问$item["@attributes"]["tag"]触发致命错误的技术求助
$item["@attributes"]["tag"] Let's break down why you're hitting this error and how to fix it.
The Root Cause
Looking at your array structure and code, the problem comes from an incorrect traversal level in your loop.
Your converted array has this hierarchy:
$xml_ray └── hold └── rec └── datafield → array of individual datafield items (each with @attributes and subfield)
But your code is looping over $xml_ray['hold']['rec'] directly:
foreach ($xml_ray['hold']['rec'] as $key_item => $item) { if ($item["@attributes"]["tag"] == $field) { // Error here // ... } }
In this loop, $item is actually the datafield array itself (not a single datafield entry). When you try to access $item["@attributes"], that key doesn't exist in the datafield array (its keys are numeric indexes like 0, 1), so PHP returns null. Trying to access ["tag"] on null triggers the "Cannot use string offset as an array" error (PHP treats null as an empty string in this context, hence the string offset error).
The Fix
Adjust your loop to target the datafield array directly, then iterate over each individual datafield entry. Also add isset() checks to guard against missing keys:
// First, get the array of datafield items $datafields = $xml_ray['hold']['rec']['datafield']; foreach ($datafields as $key_item => $item) { // Guard against missing @attributes or tag if (!isset($item["@attributes"]["tag"]) || $item["@attributes"]["tag"] !== $field) { continue; } $info_msg = "FIELD: $field <br />"; $outcame_msg .= "Found correct field $field<br />"; foreach ($item['subfield'] as $key_subfield => $subfield) { // Guard against missing subfield attributes/values if (!isset($subfield['@attributes']['code'], $subfield['@value'])) { continue; } $code = $subfield['@attributes']['code']; $value = $subfield['@value']; $info_holding_msg .= "$code = $value<br />"; if ($value == $li) { $outcame_msg .= "Found correct li in subfield $code<br />"; $checksum++; } if ($value == $loc) { $outcame_msg .= "Found correct loc in subfield $code<br />"; $checksum++; } if ($checksum == 2 && $code == $subfield_file) { $outcame_msg .= "Found subfield $code with value: $value<br />"; $checksum++; } if ($checksum == 3) { // Update the value using the correct array path $xml_ray['hold']['rec']['datafield'][$key_item]['subfield'][$key_subfield]['@value'] = $new_code; $outcame_msg .= "data found, changing data accepted."; } } }
Key Changes:
- Target the right array: We loop over
$xml_ray['hold']['rec']['datafield']instead of$xml_ray['hold']['rec']to get individual datafield entries. - Add safety checks:
isset()prevents errors if any expected keys are missing (common when dealing with XML-to-array conversions). - Correct update path: When modifying the subfield value, we use the full path to the datafield array (
$xml_ray['hold']['rec']['datafield'][$key_item]) instead of the old$xml_ray['hold']['rec'][$key_item].
Debugging Tip
If you ever hit similar array traversal issues, add a var_dump($item) inside your loop to inspect the structure of the variable you're working with. This will immediately show you if you're at the wrong level in the array hierarchy.
内容的提问来源于stack exchange,提问作者newert

