Estou tentando usar o WP Redis para armazenar em cache todo o objeto $ wp_query com a chave $ query_vars_hash .
Foi assim que $wp_query
foi adicionado a $wp_object_cache
:
add_action('wp', function($wp)
{
if ( is_admin() ) return;
global $wp_query;
if ( !wp_cache_get($wp_query->query_vars_hash, 'globals') )
{
wp_cache_add($wp_query->query_vars_hash, $wp_query, 'globals');
}
});
Em seguida, preciso verificar se uma consulta já foi armazenada em cache antes de WP_Query
recuperar as postagens:
add_action('pre_get_posts', function($query)
{
if ( is_admin() ) return;
$cached_query = wp_cache_get($query->query_vars_hash, 'globals');
if ($cached_query)
{
$GLOBALS['wp_query'] = &$cached_query;
return; // Return immediately to prevent retrieving posts again.
}
});
Problema :
return
ou exit
não funciona neste caso. Em seguida, WP_Query
ainda atingirá o banco de dados para recuperar as postagens novamente.
Pergunta :
Independentemente do plug-in, é possível parar completamente a WP_Query
recuperação de postagens?
return
pode ser o único comando que podemos chamar nesse caso.Respostas:
No momento, não é possível.
Quando
'pre_get_posts'
executado, é muito tarde para pararWP_Query
para executar uma consulta.O próprio WordPress, quando você tenta consultar uma taxonomia que não existe, adiciona
AND (0 = 1)
àWHERE
cláusula da consulta SQL, para garantir que ela não retorne resultados muito rapidamente ...Há um bilhete de trac com um patch que provavelmente irá cair no núcleo com WP 4.6, que introduz um novo filtro:
'posts_pre_query'
. O retorno de uma matriz nesse filtroWP_Query
interromperá o processamento e usará a matriz fornecida como sua matriz de postagens.De alguma forma, isso pode ajudá-lo a implementar o que você está tentando fazer.
Esperando por isso, qualquer coisa que você possa fazer é de alguma forma burra , o truque que o próprio núcleo usa também é bastante burro.
Recentemente, estou começando a usar um truque quando quero parar o WordPress para fazer coisas que não consigo parar de maneira limpa: lanço uma exceção e a pego para continuar o fluxo do aplicativo.
Eu vou te mostrar um exemplo. Observe que todo o código aqui é completamente não testado.
Primeiro de tudo, vamos escrever uma exceção personalizada:
A exceção foi projetada para atuar como uma espécie de DTO para transportar um objeto de consulta, para que em um
catch
bloco você possa obtê-lo e usá-lo.Melhor explicado com o código:
Isso deve funcionar mais ou menos, no entanto, existem muitos ganchos que você não vai disparar, por exemplo,
"the_posts"
e muito mais ... se você tiver um código que use um desses ganchos para acioná-lo, ele será quebrado.Você pode usar a
cached_query_set
função para acionar alguns dos ganchos que seu tema / plug-in pode exigir.fonte
do_action
deveria estar emtry
bloco.Esta é uma questão de PHP mais do que uma questão de WordPress.
Como o @Mark comentou:
Isso é verdade. Colocar
return
na função significa sair da função e colocar retorno em um arquivo PHP significa sair do arquivo. Não se confunda com a construção do PHPexit()
: P (Você pode encontrar uma resposta melhor no SO sobre PHPreturn
).E para responder sua pergunta
Você pode reduzir a carga da consulta buscando uma única coluna em vez da tabela completa. Como @birgire fez aqui Remover a consulta da página inicial
Pode ser uma resposta melhor ainda por vir. Acabei de compartilhar que o que eu sei :)
fonte
posts_request
filtro? Com essa abordagem de + coluna única, saímosWP_Query
mais cedo do que usando oposts_pre_query
filtro. Também observe as postagens adesivas composts_pre_query
mas podemos removê-las com$q->set( 'ignore_sticky_posts', 1 );
, por exemplo, o exemplo aqui .posts_pre_query
que não ajuda. Sua solução é a melhor até agora. :) Se você souber como podemos sair da consulta logo apóspre_get_posts
, isso pode ser ótimo. Obrigado!posts_pre_query
estará disponível a partir de 4.6;)WP_Query
classe com umget_posts()
método personalizado , com uma possível existência antecipada e que chamaparent::get_posts()
e tentar substituir a consulta relevante por ela. Mas eu não sei se isso iria funcionar ou fazer sentido com o seu caso aqui ;-) @ DanIsso será possível no 4.6 (assumindo que não há alterações até o lançamento) com o novo
posts_pre_query
filtro https://core.trac.wordpress.org/ticket/36687fonte
Sim, é possível, dependendo do que você deseja armazenar em cache. Fiz uma coisa semelhante para armazenar em cache o loop principal em nossa página inicial. Essencialmente, você pode usar as teclas
posts_request
eposts_results
para seqüestrar a consulta e acessar o cache. Em seguida, use tambémfound_posts
para corrigir a paginação.Exemplo realmente grosseiro retirado do nosso código (não testado), mas você deve ajudá-lo a ter a ideia:
Mais aqui: https://www.reddit.com/r/Wordpress/comments/19crcn/best_practice_for_hijacking_main_loop_and_caching/
fonte