Есть функция, которая, используя библиотеку
phpQuery, парсит данные со страницы на сайте. Данные на странице обновляются регулярно, поэтому функция вызывается в цикле приблизительно каждые 5-10 секунд (в зависимости от скорости получения страницы). После продолжительной работы скрипта, получаю ошибку
PHP Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 1073741824 bytes) in C:\OSPanel\domains\home-page-parcer.ru\phpQuery.php on line 3494
В php.ini memory_limit = 1536M. Скрипт работает на локальном сервере (OpenServer).
Провел небольшие исследования расставив в различных частях скрипта
memory_get_usage. Потребляемая память увеличивается непосредственно после создания объекта
phpQuery или после одного из циклов
foreach (1-го либо 2-го сверху) , при этом память не уменьшается после вызова
phpQuery::unloadDocuments(). Также, память накапливается не после каждого создания объекта phpQuery, а как-то периодически (один раз в несколько итераций, закономерность увеличения не удалось установить). К примеру: было
2097152 после стало
4194304, спустя несколько итераций значение не изменялось, но после снова увеличилось и стало
6291456.
Собственно сама функция. Не могу понять в чем проблема и почему
phpQuery::unloadDocuments(); не работает
function parcer($url){
$ids=[];
$indexIds=0;
$content = get_content($url);
$doc = phpQuery::newDocument($content);
foreach ($doc->find('[id^=name_]:input') as $opt) { // получаем товары которые успели преобразоваться в input
$opt=pq($opt);
$numTov = preg_replace('~[^0-9]*~','',$opt->attr('id')); // получаем с ID номер товара
$ids[$indexIds][] = $numTov;
$ids[$indexIds][] = $opt->attr('value'); // получаем значение input
$ids[$indexIds][] = $opt->nextAll('input:first-of-type')->prev('a')->text(); //ищем последнюю ссылку каталога
$ids[$indexIds][] = $opt->nextAll('nobr')->children('[id^=manf]')->text(); //ищем поставщика
$indexIds++;
}
foreach ($doc->find('td>[id^=name_]:not(:input)') as $opt) { // получаем товары в span, которые без родителя
$opt=pq($opt);
$numTov = preg_replace('~[^0-9]*~','',$opt->attr('id'));
$ids[$indexIds][] = $numTov;
$ids[$indexIds][]= $opt->text();
$ids[$indexIds][] = $opt->nextAll('[id^=cats_]:last')->text();
$ids[$indexIds][] = $opt->nextAll('nobr')->children('[id^=manf]')->text();
$indexIds++;
}
foreach ($doc->find('div>[id^=name_]') as $opt) { // получаем товары в span, которые с родителем
$opt=pq($opt);
$numTov = preg_replace('~[^0-9]*~','',$opt->attr('id'));
$ids[$indexIds][] = $numTov;
$ids[$indexIds][]= $opt->text();
$ids[$indexIds][] = $opt->parent()->nextAll('[id^=cats_]:last')->text();
$ids[$indexIds][] = $opt->parent()->nextAll('nobr')->children('[id^=manf]')->text();
$indexIds++;
}
phpQuery::unloadDocuments(); //очистка документа
gc_collect_cycles(); // принудительный вызов встроенного сборщика мусора PHP
return $ids;
}