Heute habe ich ein bisschen mit einer XML-Datei und der PHP-Funktion simplexml_load_file arbeiten müssen. Dabei trat der Fehler: Warning Illegal offset type in... auf...
Problem
Die simplexml_load_file Funktion wirklich sehr simpel von der der Handhabung. Eine echte Erleichterung. Nun musste ich ein kleine XML-Datei mit dieser Funktion einlesen. Dabei kam es zu folgendem Fehler der eine Warnung ausgab: Warning: Illegal offset type in foo.php on line 19. Der Inhalt der XML-Datei steht in Listing 1 und der Beispielcode steht in Listing 2.
Listing 1 - XML-Datei
Download Code!
<list>
<item>
<name>Eins</name>
</item>
<item>
<name>Zwei</name>
</item>
<item>
<name>Drei</name>
</item>
</list>
Listing 2 - foo.php
Download Code!
<?php
// XML-Datei die zu laden ist
$file = 'Test.xml';
// Laden der XML-Datei
$xml = simplexml_load_file($file);
// Ein Array auf dessen Schlüssel zugegriffen wird.
$someArray = array('Zwei' => 'Zwei ist zwei!', 'Vier' => 'Vier ist vier');
// Durchlaufen der Elemente
foreach ($xml as $item) {
// Wenn es ein Element gibt mit dem Namen zwei
if($item->name == 'Zwei') {
// Nutze es als Schlüssel für das Array und gib den Wert aus
echo $someArray[$item->name]; }
}
?>
Gut, PHP sagt uns eigentlich schon was daran falsch ist. Aber vorher noch eine kleine Anmerkung. Eigentlich sollte es schon in bei der If-Anweisung vorher eine Warning geben. Das passiert aber nicht. Warum? Weil PHP sehr großzügig mit Typen und deren Werten umgeht. Sehen kann man das in Listing 3. Umgehen kann man das indem man mit einem dreifachen Gleichheitszeichen === das schreibt. Aber dazu ein andermal mehr..
Listing 3
Download Code!
<?php
$x = '42';
if($x == 42) {
echo 'Die Antwort ist 42.'; }
?>
Zurück zum Problem mit dem Warning Illegal offset type. PHP sagt uns das der Typ für den Schlüssel falsch ist. Wenn wir davor ein gettype setzen (Listing 4), sehen wir, dass $item->name ein Objekt ist.
Listing 4
Download Code!
<?php
...
// Durchlaufen der Elemente
foreach ($xml as $item) {
// Wenn es ein Element gibt mit dem Namen zwei
if($item->name == 'Zwei') {
// Ausgabe des Typs
// Nutze es als Schlüssel für das Array und gib den Wert aus
echo $someArray[$item->name]; }
}
?>
Lösung
Die Lösung ist recht trivial. Durch eine kleine Typkonvertierung (Cast), wird aus dem Objekt ein String und ist somit als Schlüssel nutzbar. Wir setzen also ein (string) vor das $item->name und Casten so das Objekt zu einem String. Das komplette funktionierende Script steht in Listing 5.
Listing 5
Download Code!
<?php
// XML-Datei die zu laden ist
$file = 'Test.xml';
// Laden der XML-Datei
$xml = simplexml_load_file($file);
// Ein Array auf dessen Schlüssel zugegriffen wird.
$someArray = array('Zwei' => 'Zwei ist zwei!', 'Vier' => 'Vier ist vier');
// Durchlaufen der Elemente
foreach ($xml as $item) {
// Wenn es ein Element gibt mit dem Namen zwei
if($item->name == 'Zwei') {
// Nutze es als Schlüssel für das Array und gib den Wert aus
// Beachte die Typconvertierung mit (string)
echo $someArray[(string
)$item->name]; }
}
?>