Intereting Posts
Как получить значения формы вкладки в ajax в другой php-файл? Последние 2 буквы uri, определяющие используемый язык API Twitter: не получение электронной почты пользователя – Yii2 Symfony2 Удалить запись из таблицы Классы PHP, почему используется общедоступное ключевое слово? Подключение к mysql в xampp без пароля как получить идентификатор видео из iframe из youtube в php или cakephp php string в формате даты, добавьте 12 часов проблема с извлечением записей базы данных в codeigniter Ошибка PHP (MySQL): «Предупреждение: mysql_num_rows () ожидает, что параметр 1 будет ресурсом» PHP __destruct вызывает net :: ERR_CONNECTION_RESET register_shutdown_function нет. Какая разница? Поиск столбца с использованием ввода и получение строки при совпадении ввода phpmyadmin Ошибка с php7: Отсутствует расширение json Динамически создавать уникальный идентификатор для массива полей ввода, используя Javascript Zend DB Выбрать с несколькими объединениями таблиц

Обработка больших файлов JSON в PHP

Я пытаюсь обрабатывать несколько больших (возможно, до 200 М) файлов JSON. Структура файла в основном представляет собой массив объектов.

Так что что-то вроде:

[ {"property":"value", "property2":"value2"}, {"prop":"val"}, ... {"foo":"bar"} ] 

Каждый объект имеет произвольные свойства и не обязательно делится ими с другими объектами в массиве (как, например, с тем же).

Я хочу применить обработку к каждому объекту в массиве, и поскольку файл потенциально огромен, я не могу сломать весь файл в памяти, декодировать JSON и итерации по массиву PHP.

Поэтому в идеале я хотел бы прочитать файл, получить достаточную информацию для каждого объекта и обработать его. Подход типа SAX был бы в порядке, если бы была доступна аналогичная библиотека для JSON.

Любое предложение о том, как лучше справляться с этой проблемой?

Я решил работать над парсером, основанным на событиях. Это еще не совсем сделано и отредактирует вопрос со ссылкой на мою работу, когда я выложу удовлетворительную версию.

РЕДАКТИРОВАТЬ:

Я, наконец, разработал версию парсера, которой я доволен. Он доступен на GitHub:

https://github.com/kuma-giyomu/JSONParser

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

Я написал потоковый JSON pull parser pcrov / JsonReader для PHP 7 с api на основе XMLReader .

Он значительно отличается от анализаторов, основанных на событиях, тем, что вместо того, чтобы настраивать обратные вызовы и позволять синтаксическому анализатору делать свое дело, вы вызываете методы в синтаксическом анализаторе для перемещения или получения данных по желанию. Нашли нужный бит и хотите прекратить разбор? Затем прекратите разбор (и вызовите close() потому что это хорошая вещь.)

(Немного более длинный обзор синтаксических схем, связанных с событиями на основе событий, см. В моделях XML-читателей: SAX и XML-парсер .)


Пример 1:

Прочитайте каждый объект в целом из своего JSON.

 use pcrov\JsonReader\JsonReader; $reader = new JsonReader(); $reader->open("data.json"); $reader->read(); // Outer array. $depth = $reader->depth(); // Check in a moment to break when the array is done. $reader->read(); // Step to the first object. do { print_r($reader->value()); // Do your thing. } while ($reader->next() && $reader->depth() > $depth); // Read each sibling. $reader->close(); 

Вывод:

 Array ( [property] => value [property2] => value2 ) Array ( [prop] => val ) Array ( [foo] => bar ) 

Объекты возвращаются в виде массивов с строгими ключами (частично) до крайних случаев, когда действительный JSON создает имена свойств, которые не допускаются в объектах PHP. Работа над этими конфликтами не стоит, так как анонимный объект stdClass не имеет значения в простейшем массиве.


Пример 2:

Прочитайте каждый именованный элемент отдельно.

 $reader = new pcrov\JsonReader\JsonReader(); $reader->open("data.json"); while ($reader->read()) { $name = $reader->name(); if ($name !== null) { echo "$name: {$reader->value()}\n"; } } $reader->close(); 

Вывод:

 property: value property2: value2 prop: val foo: bar 

Пример 3:

Прочитайте каждое свойство данного имени. Бонус: чтение из строки вместо URI, а также получение данных из свойств с дублирующимися именами в одном и том же объекте (что разрешено в JSON, как весело).

 $json = <<<'JSON' [ {"property":"value", "property2":"value2"}, {"foo":"foo", "foo":"bar"}, {"prop":"val"}, {"foo":"baz"}, {"foo":"quux"} ] JSON; $reader = new pcrov\JsonReader\JsonReader(); $reader->json($json); while ($reader->read("foo")) { echo "{$reader->name()}: {$reader->value()}\n"; } $reader->close(); 

Вывод:

 foo: foo foo: bar foo: baz foo: quux 

Как именно лучше всего читать ваш JSON зависит от его структуры и того, что вы хотите с ней делать. Эти примеры должны дать вам место для начала.

Существует нечто подобное, но только для C ++ и Java . Насколько я знаю, если вы не можете получить доступ к одной из этих библиотек с PHP, для PHP нет реализации, но json_read() . Однако, если json структурирован так просто, легко просто прочитать файл до следующего } а затем обработать JSON, полученный через json_read() . Но вам лучше сделать это буферизированное, например, чтение 10kb, split by}, если не найдено, прочитайте еще 10k, а затем обработайте найденные значения. Затем прочитайте следующий блок и так далее.

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

https://github.com/salsify/jsonstreamingparser

Существует http://github.com/sfalvo/php-yajl/ Я не использовал его сам.