php - Jak naprawić ten niedozwolony błąd typu przesunięcia

90

Dostaję

niedozwolony typ offsetu

błąd dla każdej iteracji tego kodu. Oto kod:

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

print_r($s)
Steven
źródło
10
Ostrzeżenie: prawie wszystkie odpowiedzi (oprócz zombata) zakładają, że $sourcejest to przykład SimpleXMLi dostarczają informacji, które dotyczą tylko tej konkretnej sytuacji. Chociaż ostatecznie tak się stało, w pytaniu tego nie stwierdzono, a ktokolwiek przyjeżdża tutaj w celach informacyjnych, powinien to wziąć pod uwagę.
Álvaro González

Odpowiedzi:

157

Niedozwolone błędy typu przesunięcia występują podczas próby uzyskania dostępu do indeksu tablicy przy użyciu obiektu lub tablicy jako klucza indeksu.

Przykład:

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

Twoja $xmltablica zawiera obiekt lub tablicę pod adresem $xml->entry[$i]->sourcedla pewnej wartości $i, a kiedy spróbujesz użyć tego jako klucza indeksu dla $s, otrzymasz to ostrzeżenie. Musisz upewnić się, że $xmlzawiera to, czego chcesz i że uzyskujesz do niego dostęp poprawnie.

zombat
źródło
źródło zawiera html, czy ta klasa jest obiektem?
Steven
Czy utworzyłeś $xmlzmienną używając jakiegoś parsera XML? simple_xml czy DOMDocument? W takim przypadku jest prawdopodobne, że węzeł źródłowy jest w rzeczywistości jakimś rodzajem obiektu elementu dom.
zombat
używam simplexml_load_string. To pomaga?
Steven
Twój kod HTML mógł zostać przeanalizowany jako XML i prawdopodobnie wszystkie tagi stały się węzłami. Na przykład, jeśli masz fragment kodu HTML „<div> Cześć </div>” jako właściwość źródłową, prawdopodobnie masz coś takiego jak $xml->entry[$i]->source->div. Jeśli chcesz przeanalizować HTML do struktury DOM, DomDocumentma loadHTML()funkcję, która obsługuje HTML znacznie lepiej niż SimpleXML. Sprawdź php.net/manual/en/domdocument.loadhtml.php
zombat
Dziękuję za to. Użyłem str_replace, aby usunąć HTML i działa.
Steven
26

Użyj trim($source)przed $s[$source].

Zafer
źródło
3
Myślę, że to jest właściwa odpowiedź na to pytanie, a nie zombat
Pmpr
5
Przycinanie obiektu jest po prostu nieoczywistym sposobem rzutowania go na łańcuch (najprostszy byłby (string)$source), a wyniki zależą całkowicie od jego implementacji __toString () . Działa, jeśli masz SimpleXMLobiekt (coś, co najwyraźniej wszyscy przyjęli, ale nigdy tak naprawdę nie zostało wyrażone w pytaniu).
Álvaro González
Jeśli ten problem jest związany z implementacją __toString (), wywołanie trim () nie jest czystym rozwiązaniem. To wprowadza zamieszanie.
Čamo
3

check $ xml-> pozycja [$ i] istnieje i jest obiektem przed próbą uzyskania jego właściwości

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

lub $ source może nie być prawidłowym przesunięciem tablicy, ale tablicą, obiektem, zasobem lub prawdopodobnie wartością null

brian_d
źródło
2
Jedyna prawidłowa odpowiedź. Musisz sprawdzić istnienie elementu w tablicy. Jeśli nie istnieje, nie możesz uzyskać dostępu do jego właściwości.
RWC
0

Prawdopodobnie w Twoim xml jest mniej niż 20 wpisów.

zmień kod na ten

for ($i=0;$i< sizeof($xml->entry); $i++)
...
Byron Whitlock
źródło
4
Niezdefiniowany indeks całkowity nie generuje ostrzeżenia „Niedozwolone przesunięcie”, zamiast tego otrzymasz „Niezdefiniowany indeks” E_NOTICE.
zombat
0

Miałem podobny problem. Ponieważ otrzymałem Character od mojego dziecka XML, musiałem najpierw przekonwertować go na String (lub Integer, jeśli się spodziewasz). Poniżej pokazano, jak rozwiązałem problem.

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