Разбор большого файла JSON [дубликат]
На этот вопрос уже есть ответ здесь:
- Обработка больших файлов JSON в PHP 5 ответов
Я работаю над скриптом cron, который обращается к API, получает файл JSON (большой массив объектов) и сохраняет его локально. Как только это будет завершено, другой скрипт должен проанализировать загруженный файл JSON и вставить каждый объект в MySQL база данных.
В настоящее время я использую file_get_contents()
вместе с json_decode()
. Это позволит попытаться прочитать весь файл в память, прежде чем пытаться его обработать. Это было бы прекрасно, за исключением того факта, что мои файлы JSON обычно варьируются от 250 МБ до 1 ГБ+. Я знаю, что могу увеличить свой лимит памяти PHP, но, похоже, это не самый лучший ответ на мой взгляд. Я знаю, что могу запустить fopen()
и fgets()
, чтобы прочитать файл построчно, но мне нужно прочитать файл по каждому объекту json.
Есть ли способ чтения в файле для каждого объекта или есть другой аналогичный подход?
3 answers
Это действительно зависит от того, что содержат файлы json.
Если открытие файла одним выстрелом в память не является опцией, ваш единственный другой вариант, как вы ускользнули, - это fopen/fgets.
Возможно построчное чтение, и если эти объекты json имеют согласованную структуру, вы можете легко определить, когда начинается и заканчивается объект json в файле.
Как только вы соберете весь объект, вы вставите его в базу данных, а затем перейдете к следующему.
Больше в этом ничего нет. алгоритм определения начала и конца объекта json может усложняться в зависимости от вашего источника данных, но я уже делал что-то подобное раньше с гораздо более сложной структурой (xml), и он работал нормально.
Попробуйте эту библиотеку https://github.com/shevron/ext-jsonreader
Существующий ext/json, поставляемый с PHP, очень удобен и прост в использовании, но он неэффективен при работе с большими количество данных JSON, так как для этого требуется считывать все данные JSON в память (например, с помощью file_get_contents()), а затем сразу преобразовывать их в переменную PHP - для больших наборов данных это занимает много памяти.
JsonReader разработан для экономии памяти - он работает с потоками и может считывать данные JSON из любого потока PHP без загрузки всех данных в память. Это также позволяет разработчику извлекать определенные значения из потока JSON без декодирования и загрузки всех данных в память.
Наилучшее возможное решение:
Используйте какой-либо разделитель (разбивка на страницы, временная метка, идентификатор объекта и т.д.), Который позволяет считывать данные небольшими порциями по нескольким запросам. Это решение предполагает, что у вас есть какой-то контроль над тем, как создаются эти файлы JSON. Я основываю свое предположение на:
Это было бы прекрасно, за исключением того факта, что мои файлы JSON обычно варьируются от 250 МБ до 1 ГБ+.
Считывание и обработка 1 ГБ данных JSON это просто смешно. Определенно необходим лучший подход.