php - Как исправить эту ошибку недопустимого типа смещения

90

я собираюсь

недопустимый тип смещения

ошибка для каждой итерации этого кода. Вот код:

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

print_r($s)
Стивен
источник
10
Предупреждение: почти все ответы (кроме зомбатов) предполагают, что $sourceэто экземпляр, SimpleXMLи предоставляют информацию, которая применима только к этой конкретной ситуации. Хотя в конечном итоге так и произошло, вопрос не утверждал этого, и всякий, кто приходит сюда для справки, должен это учитывать.
Álvaro González

Ответы:

157

Ошибки недопустимого типа смещения возникают, когда вы пытаетесь получить доступ к индексу массива, используя объект или массив в качестве ключа индекса.

Пример:

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

Ваш $xmlмассив содержит объект или массив $xml->entry[$i]->sourceдля некоторого значения $i, и когда вы попытаетесь использовать это в качестве ключа индекса для $s, вы получите это предупреждение. Вам нужно будет убедиться, что он $xmlсодержит то, что вы хотите, и что вы получаете к нему правильный доступ.

зомбат
источник
источник содержит HTML, этот класс как объект?
Стивен
Вы создавали $xmlпеременную с помощью какого-то анализатора XML? simple_xml или DOMDocument? В этом случае вполне вероятно, что исходный узел на самом деле является каким-то объектом элемента dom.
зомбат
я использую simplexml_load_string. это помогает?
Стивен
Ваш HTML мог быть проанализирован как XML, и, вероятно, все ваши теги стали узлами. Например, если в качестве исходного свойства у вас есть фрагмент HTML «<div> Hi </div>», то у вас, вероятно, есть что-то вроде $xml->entry[$i]->source->div. Если вы хотите преобразовать HTML в структуру DOM, у вас DomDocumentесть loadHTML()функция, которая обрабатывает HTML намного лучше, чем SimpleXML. Проверьте php.net/manual/en/domdocument.loadhtml.php
zombat
Спасибо за это. Я использовал str_replace, чтобы удалить html, и он работает.
Стивен
26

Использовать trim($source)раньше $s[$source].

Зафер
источник
3
Я думаю, что это правильный ответ на этот вопрос, а не вопрос о зомбате
Pmpr
5
Обрезка объекта - это просто неочевидный способ преобразовать его в строку (самый простой будет (string)$source), и результаты полностью зависят от его реализации __toString () . Это работает, если у вас есть SimpleXMLобъект (что-то, очевидно, предполагаемое всеми, но никогда не указанное в вопросе).
Альваро Гонсалес
Если проблема связана с реализацией __toString (), вызов trim () не является чистым решением. Это сбивает с толку.
Čamo 07
3

проверьте, что $ xml-> entry [$ i] существует и является объектом, прежде чем пытаться получить его свойство

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

или $ source может быть не допустимым смещением массива, а массивом, объектом, ресурсом или, возможно, null

brian_d
источник
2
Единственно правильный ответ. Вы должны проверить наличие элемента в массиве. Если он не существует, вы не можете получить доступ к его свойствам.
RWC
0

Вероятно, в вашем xml меньше 20 записей.

измените код на этот

for ($i=0;$i< sizeof($xml->entry); $i++)
...
Байрон Уитлок
источник
4
Неопределенный целочисленный индекс не генерирует предупреждение «Недопустимое смещение», вместо этого вы получите «Неопределенный индекс» E_NOTICE.
зомбат,
0

У меня была аналогичная проблема. Поскольку я получил символ от моего ребенка XML, мне пришлось сначала преобразовать его в строку (или целое число, если вы этого ожидаете). Ниже показано, как я решил проблему.

foreach($xml->children() as $newInstr){
        $iInstrument = new Instrument($newInstr['id'],$newInstr->Naam,$newInstr->Key);
        $arrInstruments->offsetSet((String)$iInstrument->getID(), $iInstrument);
    }
user8387356
источник