Intereting Posts
array_map для коллекции с интерфейсами массива? Как безопасно хранить файлы cookie, содержащие конфиденциальные данные, в PHP? Проверьте, существует ли значение HTML5 sessionStorage с PHP (например, с помощью файлов cookie) Как сохранить XML с помощью PHP как я могу удалить тестовый заказ от magento Обрезка блока текста до ближайшего слова, когда достигается определенный предел символов? php включают отпечатки 1 Доступ к данным сеанса за пределами Joomla MySQL, объединить два столбца Преобразование специальных символов (другого языка) на английский в PHP Как использовать DATE () в Doctrine 2 DQL? Регулярное выражение для строки, которая должна содержать минимум 14 символов, где минимум 2 – числа, а минимум 6 – буквы Получить родительскую папку текущего файла PHP Геокодирование Google Maps работает от браузера, но не от PHP-сервера MySQL / PHP: поиск похожих / связанных элементов по тегам / таксономии

Неопределенное смещение при доступе к элементу массива, который существует

У меня есть массив и PHP, и когда я его распечатываю, я вижу значения, которые мне нужны для доступа, но когда я пытаюсь получить их по их ключу, я получаю уведомление PHP. Я напечатал массив с помощью print_r :

Array ( [207] => sdf [210] => sdf ) 

Когда я пытаюсь получить доступ к массиву с помощью индекса, я получаю неопределенное уведомление о смещении. Вот мой код:

 print_r($output); echo $output[207]; // Undefined Offset echo $output["207"]; // Undefined Offset 

Массив $output является результатом вызова array_diff_key и первоначально вводится как JSON через HTTP POST-запрос.

array_keys дает мне следующее:

 Array ( [0] => 207 [1] => 210 ) 

В ответ на комментарии:

var_dump(key($output)); выходы:

  string(3) "207" 

var_dump(isset($output[key($output)])); выходы:

  bool(false) 

Solutions Collecting From Web of "Неопределенное смещение при доступе к элементу массива, который существует"

См. Этот раздел о преобразовании объекта в массив в руководстве PHP :

Ключи – это имена переменных-членов, с несколькими заметными исключениями: целочисленные свойства недоступны ; частные переменные имеют имя класса, добавленное к имени переменной; защищенные переменные имеют «*», добавленные к имени переменной.

При преобразовании в массив из объекта в PHP целые массивные ключи хранятся внутри как строки. Когда вы обращаетесь к элементам массива в PHP или обычно используете массив, ключи, содержащие действительные целые числа, будут автоматически преобразованы в целые числа. Целое число, сохраненное внутри строки в виде строки, является недоступным ключом.

Обратите внимание на разницу:

 $x = (array)json_decode('{"207":"test"}'); var_dump(key($x)); // string(3) "207" var_dump($x); // array(1) { // ["207"]=> // string(4) "test" // } $y['207'] = 'test'; var_dump(key($y)); // int(207) var_dump($y); // array(1) { // [207]=> // string(4) "test" // } 

print_r на обоих этих массивах дает идентичный результат, но с var_dump вы можете видеть различия.

Вот какой код, который воспроизводит вашу точную проблему:

 $output = (array)json_decode('{"207":"sdf","210":"sdf"}'); print_r($output); echo $output[207]; echo $output["207"]; 

И простое исправление заключается в передаче true для json_decode для необязательного аргумента-аргумента, чтобы указать, что вы хотите, чтобы массив не был объектом:

 $output = json_decode('{"207":"sdf","210":"sdf"}', true); print_r($output); echo $output[207]; echo $output["207"]; 

Проблема возникает при приведении в array объекта, у которого есть строковые ключи, которые являются действительными целыми числами.

Если у вас есть этот объект:

 object(stdClass)#1 (2) { ["207"]=> string(3) "sdf" ["210"]=> string(3) "sdf" } 

и вы бросаете его с помощью

 $array = (array)$object 

вы получаете этот массив

 array(2) { ["207"]=> string(3) "sdf" ["210"]=> string(3) "sdf" } 

который имеет ключи, к которым можно получить доступ только путем их циклического перехода, поскольку прямой доступ, такой как $array["207"] , всегда будет преобразован в $array[207] , которого не существует.

Поскольку вы получаете объект, подобный вышеперечисленному, из json_decode() применяемого к строке типа

 $json = '{"207":"sdf", "210":"sdf"}' 

Лучшим решением было бы избежать, в первую очередь, цифровых клавиш. Вероятно, они лучше моделируются как числовые свойства массива объектов:

 $json = '[{"numAttr":207, "strAttr":"sdf"}, {"numAttr":210, "strAttr":"sdf"}]' 

Эта структура данных имеет несколько преимуществ по сравнению с существующей:

  1. он лучше отражает исходные данные, как набор объектов, которые имеют числовое свойство
  2. он легко расширяется с другими свойствами
  3. он более переносим в разных системах (как вы видите, ваша текущая структура данных вызывает проблемы на PHP, но если вам придётся использовать другой язык, вы можете легко столкнуться с подобными проблемами).

Если требуется свойство map → object map, оно может быть быстро получено, например:

 function getNumAttr($obj) { return $obj->numAttr; } // for backward compatibility $arr = json_decode($json); // where $json = '[{"numAttr":... $map = array_combine(array_map('getNumAttr', $arr), $arr); 

Другим решением было бы сделать так, как предложил ascii-lime: force json_decode() для вывода ассоциативных массивов вместо объектов, установив свой второй параметр в true :

 $map = json_decode($json, true); 

Для ваших входных данных это производит напрямую

 array(2) { [207]=> string(3) "sdf" [210]=> string(3) "sdf" } 

Обратите внимание, что ключи массива теперь являются целыми числами вместо строк.

Я бы подумал об изменении структуры данных JSON гораздо более чистого решения, хотя, хотя я понимаю, что это может быть невозможно.

Я только что нашел эту ошибку, которая заставляет элементы массива быть недоступными иногда в PHP, когда массив создается вызовом unserialize .

Создайте тестовый PHP-файл, содержащий (или запустите из командной строки) следующий скрипт:

 <?php $a = unserialize('a:2:{s:2:"10";i:1;s:2:"01";i:2;}'); print $a['10']."\n"; $a['10'] = 3; $a['01'] = 4; print_r($a); foreach ($a as $k => $v) { print 'KEY: '; var_dump($k); print 'VAL: '; var_dump($v); print "\n"; } 

Если вы получаете ошибки, у вас есть версия PHP с этой ошибкой, и я рекомендую перейти на PHP 5.3

Пытаться

 var_dump($output); foreach ($output as $key => val) { var_dump($key); var_dump($val); } 

чтобы узнать больше о том, что происходит.

Какая точная строка / заявление бросает вам предупреждение?

Как вы напечатали массив? Я бы предложил print_r($arrayName);

Затем вы можете печатать отдельные элементы, такие как: echo $arrayName[0];

Попробуйте использовать мой подход:

 class ObjectToArray { public static function convert( $object ) { if( !is_object( $object ) && !is_array( $object ) ) { return $object; } if( is_object( $object ) ) { $object = get_object_vars( $object ); } return array_map( 'ObjectToArray::convert', $object ); } } $aNewArray = ObjectToArray::convert($oYourObject); 

Просто поставьте error_reporting (0); в вашем методе или при запуске файла. Это решит вашу проблему.