php - ¿Cómo soluciono este error de tipo de compensación ilegal?

90

Me estoy poniendo

tipo de compensación ilegal

error para cada iteración de este código. Aquí está el código:

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

print_r($s)
Steven
fuente
10
Advertencia: casi todas las respuestas (excepto las de zombat) asumen que $sourcees una instancia SimpleXMLy proporcionan información que solo se aplica a esa situación específica. Si bien ese fue finalmente el caso, la pregunta no lo expresó y quienquiera que venga aquí como referencia debe tener esto en cuenta.
Álvaro González

Respuestas:

157

Los errores de tipo de desplazamiento ilegal ocurren cuando intenta acceder a un índice de matriz utilizando un objeto o una matriz como clave de índice.

Ejemplo:

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

Su $xmlmatriz contiene un objeto o matriz en $xml->entry[$i]->sourcepor algún valor de $i, y cuando intenta usar eso como clave de índice $s, obtiene esa advertencia. Tendrás que asegurarte de que $xmlcontiene lo que quieres y que estás accediendo a él correctamente.

zombat
fuente
la fuente contiene html, ¿esa clase es un objeto?
Steven
¿Creó la $xmlvariable utilizando algún tipo de analizador XML? simple_xml o DOMDocument? En ese caso, es probable que el nodo de origen sea en realidad algún tipo de objeto de elemento dom.
zombat
Estoy usando simplexml_load_string. ¿Eso ayuda?
Steven
Es posible que su HTML haya sido analizado como XML, y probablemente todas sus etiquetas se hayan convertido en nodos. Por ejemplo, si tuvieras un fragmento HTML de "<div> Hola </div>" como tu propiedad fuente, probablemente tengas algo como $xml->entry[$i]->source->div. Si desea analizar HTML en una estructura DOM, DomDocumenttiene una loadHTML()función que maneja HTML mucho mejor que SimpleXML. Echa un vistazo a php.net/manual/en/domdocument.loadhtml.php
zombat
gracias por eso. He usado str_replace para quitar el html y funciona.
Steven
26

Úselo trim($source)antes $s[$source].

Zafer
fuente
3
Creo que esta es la respuesta correcta para esta pregunta, no la de zombat
Pmpr
5
Recortar un objeto es solo una forma no obvia de convertirlo en una cadena (la más sencilla sería (string)$source) y los resultados dependen completamente de su implementación __toString () . Funciona si tiene un SimpleXMLobjeto (algo aparentemente asumido por todos pero nunca declarado en la pregunta).
Álvaro González
Si este problema está relacionado con la implementación de __toString (), la llamada trim () no es una solución limpia. Es confuso.
Čamo
3

comprobar $ xml-> entrada [$ i] existe y es un objeto antes de intentar obtener una propiedad del mismo

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

o $ source podría no ser un desplazamiento de matriz legal sino una matriz, objeto, recurso o posiblemente nulo

brian_d
fuente
2
La única respuesta correcta. Debe verificar la existencia del elemento en la matriz. Si no existe, no puede acceder a sus propiedades.
RWC
0

Probablemente haya menos de 20 entradas en su xml.

cambia el código a este

for ($i=0;$i< sizeof($xml->entry); $i++)
...
Byron Whitlock
fuente
4
Un índice entero indefinido no genera una advertencia de "Desplazamiento ilegal"; en su lugar, obtendría un E_NOTICE de "índice indefinido".
zombat
0

Tuve un problema similar. Como obtuve un carácter de mi hijo XML, tuve que convertirlo primero en una cadena (o entero, si lo espera). A continuación se muestra cómo resolví el problema.

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