Dica de PHP · publicada em
Quando você faz get_posts() com posts_per_page => -1 num site com cem mil posts, tudo vai para a memória de uma vez. É o caminho mais curto para o fatal de memória esgotada.
Um generator inverte isso: a função devolve um item por vez com yield, e o laço consome sob demanda. A memória fica constante, independente do total. Combinado com paginação por lotes, você percorre qualquer volume.
Detalhe importante em WordPress: chame wp_cache_flush() ou limpe o cache de objeto entre lotes em rotinas longas, senão o cache interno cresce e você volta ao mesmo problema por outro caminho.
function todos_os_posts(string $tipo = 'post', int $lote = 200): Generator {
$pagina = 1;
do {
$posts = get_posts([
'post_type' => $tipo,
'posts_per_page' => $lote,
'paged' => $pagina++,
'orderby' => 'ID',
'order' => 'ASC',
]);
foreach ($posts as $p) { yield $p; }
wp_cache_flush();
} while (count($posts) === $lote);
}
foreach (todos_os_posts('produto') as $post) { /* processa um por vez */ }
Na prática: rotina longa: generator com paginação + wp_cache_flush() entre lotes.