Как пропарсить json данные (~20 мб, сервер heroku)
У меня есть бот в ВК на PHP. И есть API расписания своего вуза. Бот стоит на heroku. API в виду большого json файла. И если его скачивать в файл (что я щас и делаю, это занимает около 20 секунд):
// crontable.php
file_put_contents($file, file_get_contents("https://example.com"));
Все это попадает в $file, далее я обрабатываю его с помощью jsonstreamingparser:
// parser.php
$file = __DIR__.'/stackoverflow.json';
$stream = fopen($file, 'r');
try {
$parser = new \JsonStreamingParser\Parser($stream, $listener);
$parser->parse();
fclose($stream);
} catch (Exception $e) {
fclose($stream);
return $e->getMessage();
}
$data = $listener->getJson();
Вот этот код у меня парсит json файл и все ок. Но, расписание обновляется каждый день и вручную мне это делать не хочется. А так как cron в heroku не может скачивать данные с другого сервера и сам обновлять файл (если может, то напишите) т.к они хранятся там временно.
The Heroku filesystem is ephemeral - that means that any changes to the filesystem whilst the dyno is running only last until that dyno is shut down or restarted. Each dyno boots with a clean copy of the filesystem from the most recent deploy. This is similar to how many container based systems, such as Docker, operate.
Примечание: ВКонтакте и пользователи не будут долго ждать, пока, с каждым запросом расписание будет скачиваться (около 20 секунд) и обрабатываться.
Вопрос: можно ли как то, не прибегая к скачиванию большого файла, быстро взять данные с API страницы и обработать их. Либо, можно ли как то сделать, чтобы heroku сам скачивал файл в определенное мне время. Спасибо :)
Ответы (1 шт):
А как Вам такое предложение: пусть файл скачивает только пользователь, который первый пришел в этот день к боту. А потом - файл уже в памяти, и скачивать его не надо. Ну, первый подождет 20 секунд, а все остальные зато - придут "на готовенькое".
То есть, как мне кажется, вам надо переменную $data использовать для всех последующих вызоов без инициализации. ну, и без обнуления, конечно :-)
Вероятно, для этого надо загрузку данных перенести в какое то более глобальное событие, чем сейчас. Грубо говоря, в интерфейсе работы с телеграмм - ботом есть событие "пришел пользователь", и сейчас у вас на приход каждого пользователя запускается тот код, который приведен в вопросе.
А еще есть событие типа "старт бота". Более глобальное, которое возникает один раз. Вот в него и надо перенести код, который загружает данные.
А в "пришел пользователь" тогда надо проверять только "переход через полночь". Полночь прошла - расписание могло измениться, надо его еще раз скачать и переинициализировать $data
Дополнение
Мне в комментариях подсказали, что с этой схемой есть трудности.
Правда, мне непонятно вот что: в коде, который есть в вопросе, я не вижу процедуры скачивания данных. А вижу только парсинг локально лежащего json файла. (я не очень хорошо понимаю, сколько времени это может занимать, но 20 секунд для 20 мб файла мне кажется слишком большим временем.)
Тогда - лучше, скорее всего, действительно скачивать данные отдельно от их парсинга. Но тут нужен или какой то знаток heroku, котрый знает, за какую ручку там подёргать, чтобы организовать что то вроде crontab. Поиск выводит меня на такую страницу - думаю, что дальше лучше разбираться Вам, так как у Вас есть доступ к хостингу :-)