php - Як виправити цю незаконну помилку типу зсуву


90

Я отримую

незаконний офсетний тип

помилка для кожної ітерації цього коду. Ось код:

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

print_r($s)

10
Попередження: майже всі відповіді (за винятком зомбатів) передбачають, що $sourceце приклад SimpleXMLі надають інформацію, яка стосується лише тієї конкретної ситуації. Хоча це врешті-решт було так, питання не містило цього, і той, хто приходить сюди для довідки, повинен це врахувати.
Альваро Гонсалес

Відповіді:


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> Привіт </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 () не є чистим рішенням. Це бентежить.
Чамо

3

перевірити $ xml-> запис [$ i] існує та є об'єктом перед спробою отримати його властивість

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

або $ source може бути не юридичним зміщенням масиву, а масивом, об’єктом, ресурсом або, можливо, нульовим значенням


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);
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.