Estoy tratando de usar WP Redis para almacenar en caché todo el objeto $ wp_query con la clave $ query_vars_hash .
Así es como $wp_query
se agregó 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');
}
});
Luego, debo verificar si una consulta ya se ha almacenado en caché antes de WP_Query
poder recuperar publicaciones:
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
o exit
no funciona en este caso. Entonces, WP_Query
todavía llegará a la base de datos para recuperar publicaciones nuevamente.
Pregunta :
Independientemente del complemento, ¿es posible dejar de WP_Query
recuperar publicaciones por completo ?
return
podría ser el único comando que podemos llamar en este caso.Respuestas:
Por el momento, no es posible.
Cuando se
'pre_get_posts'
ejecuta, es demasiado tarde para detenerseWP_Query
para realizar una consulta.WordPress en sí mismo, cuando intenta consultar una taxonomía que no existe, agrega
AND (0 = 1)
a laWHERE
cláusula de la consulta SQL, para asegurarse de que no devuelve resultados muy rápidamente ...Hay un billete trac con un parche que probablemente lo hará en tierras núcleo con WP 4.6, que introduce un nuevo filtro:
'posts_pre_query'
. Si devuelve una matriz en ese filtro, seWP_Query
detendrá el procesamiento y se usará la matriz proporcionada como matriz de publicaciones.De alguna manera, esto podría ayudarlo a implementar lo que está tratando de hacer.
A la espera de esto, cualquier cosa que puedas hacer es de alguna manera hack , el núcleo del truco en sí mismo también es bastante hack.
Recientemente, estoy comenzando a usar un truco cuando quiero detener WordPress para hacer cosas que no puedo detener de una manera limpia: lanzo una excepción y la atrapo para continuar el flujo de la aplicación.
Te mostraré un ejemplo. Tenga en cuenta que todo el código aquí no se ha probado por completo.
Antes que nada, escribamos una excepción personalizada:
La excepción está diseñada para actuar como una especie de DTO para transportar un objeto de consulta, de modo que en un
catch
bloque pueda obtenerlo y usarlo.Mejor explicado con código:
Esto debería funcionar más o menos, sin embargo, hay muchos ganchos que no vas a disparar, por ejemplo,
"the_posts"
y mucho más ... si tienes un código que usa uno de esos ganchos para disparar, se romperá.Puede usar la
cached_query_set
función para activar algunos de los ganchos que su tema / complementos pueden requerir.fuente
do_action
debería estar entry
bloque.Esta es una pregunta PHP más que una pregunta de WordPress.
Como @Mark comentó:
Eso es verdad. Colocar
return
en la función significa salir de la función y colocar el retorno en un archivo PHP significa salir del archivo. No se confunda con PHP constructexit()
: P (es posible que encuentre una mejor respuesta en SO sobre PHPreturn
).Y para responder a tu pregunta
Puede reducir la carga de consultas obteniendo una sola columna en lugar de una tabla completa. Como hizo @birgire aquí Eliminar la consulta de la página de inicio
Puede ser una mejor respuesta por venir. Acabo de compartir que lo que sé :)
fuente
posts_request
filtro? Con ese enfoque de + columna simple, salimosWP_Query
antes de usar elposts_pre_query
filtro. También tenga cuidado con las publicaciones adhesivas con,posts_pre_query
pero podemos eliminarlo, por$q->set( 'ignore_sticky_posts', 1 );
ejemplo, en el ejemplo aquí .posts_pre_query
que no ayuda. Tu solución es la mejor hasta ahora. :) Si sabes cómo podemos salir de la consulta inmediatamente despuéspre_get_posts
, eso podría ser genial. ¡Gracias!posts_pre_query
estará disponible desde 4.6;)WP_Query
clase con unget_posts()
método personalizado , con una posible existencia temprana y que llamaparent::get_posts()
e intenta anular la consulta relevante con él. Pero no sé si eso funcionaría o tendría sentido con su caso aquí ;-) @DanSerá posible en 4.6 (suponiendo que no haya cambios hasta el lanzamiento) con el nuevo
posts_pre_query
filtro https://core.trac.wordpress.org/ticket/36687fuente
Sí, es posible dependiendo de lo que quieras almacenar en caché. He hecho algo similar para almacenar en caché el bucle principal en nuestra página de inicio. Esencialmente, puede usar el
posts_request
yposts_results
para secuestrar la consulta y presionar el caché en su lugar, luego también usarfound_posts
para corregir la paginación.Ejemplo realmente tosco extraído de nuestro código (no probado) pero debería ayudarlo a tener la idea:
Más aquí: https://www.reddit.com/r/Wordpress/comments/19crcn/best_practice_for_hijacking_main_loop_and_caching/
fuente