php - Comment corriger cette erreur de type de décalage illégal

90

Je suis en train

type de décalage illégal

erreur pour chaque itération de ce code. Voici le code:

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

print_r($s)
Steven
la source
10
Attention: presque toutes les réponses (à l'exception des zombats) supposent qu'il $sources'agit d'une instance de SimpleXMLet fournissent des informations qui ne s'appliquent qu'à cette situation spécifique. Bien que ce soit finalement le cas, la question ne l'a pas dit et quiconque vient ici pour référence devrait en tenir compte.
Álvaro González

Réponses:

157

Des erreurs de type de décalage illégales se produisent lorsque vous essayez d'accéder à un index de tableau en utilisant un objet ou un tableau comme clé d'index.

Exemple:

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

Votre $xmltableau contient un objet ou un tableau à $xml->entry[$i]->sourcepour une valeur de $i, et lorsque vous essayez de l'utiliser comme clé d'index pour $s, vous obtenez cet avertissement. Vous devrez vous assurer qu'il $xmlcontient ce que vous voulez et que vous y accédez correctement.

zombat
la source
la source contient html, cette classe est-elle un objet?
Steven
Avez-vous créé la $xmlvariable en utilisant une sorte d'analyseur XML? simple_xml ou DOMDocument? Dans ce cas, il est probable que le nœud source soit en fait une sorte d'objet élément dom.
zombat
J'utilise simplexml_load_string. Est ce que ça aide?
Steven
Votre code HTML a peut-être été analysé en tant que XML et toutes vos balises sont probablement devenues des nœuds. Par exemple, si vous aviez un extrait HTML de "<div> Salut </div>" comme propriété source, alors vous avez probablement quelque chose comme $xml->entry[$i]->source->div. Si vous souhaitez analyser le HTML dans une structure DOM, DomDocumenta une loadHTML()fonction qui gère le HTML beaucoup mieux que SimpleXML. Découvrez php.net/manual/en/domdocument.loadhtml.php
zombat
Merci pour ça. J'ai utilisé str_replace pour supprimer le code HTML et cela fonctionne.
Steven
26

Utiliser trim($source)avant $s[$source].

Zafer
la source
3
Je pense que c'est la bonne réponse pour cette question, pas celle de zombat
Pmpr
5
Le découpage d'un objet n'est qu'un moyen non évident de le convertir en chaîne (le plus simple serait (string)$source) et les résultats dépendent entièrement de son implémentation __toString () . Cela fonctionne si vous avez un SimpleXMLobjet (quelque chose apparemment assumé par tout le monde mais jamais vraiment déclaré dans la question).
Álvaro González
Si ce problème est lié à l'implémentation __toString (), l'appel trim () n'est pas une solution propre. C'est confus.
Čamo
3

vérifier $ xml-> l'entrée [$ i] existe et est un objet avant d'essayer d'en obtenir une propriété

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

ou $ source peut ne pas être un décalage de tableau légal mais un tableau, un objet, une ressource ou éventuellement null

brian_d
la source
2
La seule bonne réponse. Vous devez vérifier l'existence de l'élément dans le tableau. S'il n'existe pas, vous ne pouvez pas accéder à ses propriétés.
RWC
0

Il y a probablement moins de 20 entrées dans votre xml.

changez le code en ceci

for ($i=0;$i< sizeof($xml->entry); $i++)
...
Byron Whitlock
la source
4
Un index entier non défini ne génère pas d'avertissement "Décalage illégal", vous obtiendrez un E_NOTICE "Index non défini" à la place.
zombat
0

J'avais un problème similaire. Comme j'ai obtenu un caractère de mon enfant XML, j'ai dû le convertir d'abord en une chaîne (ou un entier, si vous en attendez un). Ce qui suit montre comment j'ai résolu le problème.

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