php - Wie behebe ich diesen unzulässigen Versatzfehler?

88

Ich erhalte

unzulässiger Offset-Typ

Fehler für jede Iteration dieses Codes. Hier ist der Code:

$s = array();
for($i = 0; $i < 20; $i++){
    $source = $xml->entry[$i]->source;
    $s[$source] += 1;    
}

print_r($s)
Steven
quelle
10
Warnung: Fast alle Antworten (außer Zombat) gehen davon aus, dass $sourcees sich um eine Instanz handelt, SimpleXMLund liefern Informationen, die nur für diese bestimmte Situation gelten. Während dies letztendlich der Fall war, wurde dies in der Frage nicht angegeben, und wer auch immer als Referenz hierher kommt, sollte dies berücksichtigen.
Álvaro González

Antworten:

154

Unzulässige Fehler vom Typ Offset treten auf, wenn Sie versuchen, mit einem Objekt oder einem Array als Indexschlüssel auf einen Array-Index zuzugreifen .

Beispiel:

$x = new stdClass();
$arr = array();
echo $arr[$x];
//illegal offset type

Ihr $xmlArray enthält ein Objekt oder Array mit $xml->entry[$i]->sourceeinem Wert von $i. Wenn Sie versuchen, dieses als Indexschlüssel für zu verwenden $s, wird diese Warnung angezeigt. Sie müssen sicherstellen, dass es das $xmlenthält, was Sie möchten, und dass Sie korrekt darauf zugreifen.

Zombat
quelle
Die Quelle enthält HTML. Ist diese Klasse ein Objekt?
Steven
Haben Sie die $xmlVariable mit einem XML-Parser erstellt? simple_xml oder DOMDocument? In diesem Fall ist es wahrscheinlich, dass der Quellknoten tatsächlich eine Art Dom-Element-Objekt ist.
Zombat
Ich benutze simplexml_load_string. Hilft das?
Steven
Ihr HTML-Code wurde möglicherweise als XML analysiert, und wahrscheinlich wurden alle Ihre Tags zu Knoten. Wenn Sie beispielsweise ein HTML-Snippet von "<div> Hi </ div>" als Quelleigenschaft hatten, haben Sie wahrscheinlich so etwas wie $xml->entry[$i]->source->div. Wenn Sie HTML in eine DOM-Struktur analysieren möchten, DomDocumentverfügt diese über eine loadHTML()Funktion, die HTML viel besser verarbeitet als SimpleXML. Überprüfen Sie heraus php.net/manual/en/domdocument.loadhtml.php
zombat
Dank dafür. Ich habe str_replace verwendet, um das HTML zu entfernen, und es funktioniert.
Steven
26

Verwenden Sie trim($source)vor $s[$source].

Zafer
quelle
3
Ich denke, dies ist die richtige Antwort auf diese Frage, nicht die von Zombat
Pmpr
5
Das Trimmen eines Objekts ist nur eine nicht offensichtliche Methode, um es in einen String umzuwandeln ( der einfachste wäre (string)$source). Die Ergebnisse hängen vollständig von der Implementierung von __toString () ab . Es funktioniert, wenn Sie ein SimpleXMLObjekt haben (etwas, das anscheinend von allen angenommen, aber in der Frage nie wirklich angegeben wurde).
Álvaro González
Wenn dieses Problem mit der Implementierung von __toString () zusammenhängt, ist der Aufruf von trim () keine saubere Lösung. Es ist verwirrend.
Čamo
3

Überprüfen Sie, ob $ xml-> entry [$ i] vorhanden und ein Objekt ist, bevor Sie versuchen, eine Eigenschaft davon abzurufen

 if(isset($xml->entry[$i]) && is_object($xml->entry[$i])){
   $source = $xml->entry[$i]->source;          
   $s[$source] += 1;
 }

oder $ source ist möglicherweise kein zulässiger Array-Offset, sondern ein Array, ein Objekt, eine Ressource oder möglicherweise null

brian_d
quelle
2
Die einzig richtige Antwort. Sie müssen die Existenz des Elements im Array überprüfen. Wenn es nicht vorhanden ist, können Sie nicht auf seine Eigenschaften zugreifen.
RWC
0

Es gibt wahrscheinlich weniger als 20 Einträge in Ihrer XML.

Ändern Sie den Code in diesen

for ($i=0;$i< sizeof($xml->entry); $i++)
...
Byron Whitlock
quelle
4
Ein undefinierter ganzzahliger Index generiert keine Warnung "Unzulässiger Versatz". Stattdessen erhalten Sie einen E_NOTICE "Undefinierter Index".
Zombat
0

Ich hatte ein ähnliches Problem. Da ich von meinem XML-Kind ein Zeichen bekam, musste ich es zuerst in einen String (oder eine Ganzzahl, wenn Sie eine erwarten) konvertieren. Das Folgende zeigt, wie ich das Problem gelöst habe.

foreach($xml->children() as $newInstr){
        $iInstrument = new Instrument($newInstr['id'],$newInstr->Naam,$newInstr->Key);
        $arrInstruments->offsetSet((String)$iInstrument->getID(), $iInstrument);
    }
user8387356
quelle