Увидев этот ответ ей годами без заключения, наконец-то обновление!Теперь я столкнулся с подобной проблемой, и оказалось, что DOMXPath
просто утечка памяти, и вы не можете ее контролировать.Я не искал, если об этом сообщалось на bug.php.net до сих пор (это может быть полезно для редактирования позже).
«Рабочие» решения, которые я нашел для этой проблемы, являются просто обходными путями.Основная идея состояла в том, чтобы заменить DOMNodeList
Traversable
, возвращаемый на DOMXPath::query()
, на другой, содержащий те же узлы.
Наиболее подходящее решение - DOMXPathElementsIterator
который позволяет вам запрашивать конкретное выражение xpath, которое у вас есть в вашем вопросе, без утечек памяти:
$nodes = new DOMXPathElementsIterator($this->dom, "//span[@class='ckass']");
foreach ($nodes as $span) {
...
}
Этот класс теперь является частью версии разработки Iterator-Garden и $nodes
является итератором для всех элементов <span>
DOME.
Недостатком этого временного решения является то, что результат xpath ограничен результатом SimpleXMLElement::xpath()
(отличается от DOMXPath::query()
)потому что он используется для предотвращения утечки памяти.
Другая альтернатива - использовать DOMNodeListIterator
вместо DOMNodeList
, как тот, который возвращается DOMDocument::getElementsByTagname()
.Однако эти итерации медленные.
Надеюсь, что это пригодится, даже если вопрос был действительно старым.Это помогло мне в подобной ситуации.
Вызов кругов очистки сборки мусора имеет смысл только в том случае, если на объекты больше не ссылаются (не используют).
Например, если вы создаетеНовый DOMXPath
объект для того же DOMDocument
снова и снова (имейте в виду, что он связан с DOMDocument
, который все еще существует), звучит как утечка вашей памяти.Вы просто используете все больше и больше памяти.
Вместо этого вы можете просто повторно использовать существующий объект DOMXPath
, так как вы постоянно используете объект DOMDocument
.Попробуйте:
//Loaded outside of loop
$this->dom = new DOMDocument();
$xpath = new DOMXPath($this->dom);
//Inside Loop
$this->dom->loadHTML($output);
$nodes = $xpath->query("//span[@class='ckass']");