Ich versuche, WP Redis zu verwenden, um das gesamte $ wp_query- Objekt mit dem Schlüssel $ query_vars_hash zwischenzuspeichern .
So $wp_query
wurde hinzugefügt zu $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');
}
});
Dann muss ich überprüfen, ob eine Abfrage bereits zwischengespeichert wurde, bevor WP_Query
Beiträge abgerufen werden können:
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.
}
});
Problem :
return
oder exit
funktioniert in diesem Fall nicht. Dann WP_Query
wird immer noch Datenbank getroffen, um Beiträge wieder abzurufen.
Frage :
Ist es unabhängig vom Plugin möglich, das WP_Query
Abrufen von Posts vollständig zu beenden ?
return
könnte aber der einzige Befehl sein, den wir in diesem Fall aufrufen können.Antworten:
Im Moment ist es nicht möglich.
Wenn ausgeführt
'pre_get_posts'
, ist es zu spätWP_Query
, um eine Abfrage durchzuführen.Wenn Sie selbst versuchen, eine nicht vorhandene Taxonomie abzufragen, wird WordPress selbst
AND (0 = 1)
zurWHERE
Klausel der SQL-Abfrage hinzugefügt, um sicherzustellen, dass sehr schnell keine Ergebnisse zurückgegeben werden ...Es gibt ein Trac-Ticket mit einem Patch, der wahrscheinlich im Kern von WP 4.6 landen wird und einen neuen Filter einführt :
'posts_pre_query'
. Wenn Sie ein Array für diesen Filter zurückgeben, wird dieWP_Query
Verarbeitung gestoppt und das bereitgestellte Array als Posts-Array verwendet.Dies könnte Ihnen irgendwie helfen, das umzusetzen, was Sie versuchen zu tun.
Warten fot das, was Sie tun können , ist irgendwie hackish , der Trick selbst Kern nutzt auch ganz hackish ist.
Vor kurzem verwende ich einen Trick, wenn ich WordPress stoppen möchte, um Dinge zu tun, die ich nicht sauber stoppen kann: Ich löse eine Ausnahme und fange sie ab, um den Anwendungsfluss fortzusetzen.
Ich zeige Ihnen ein Beispiel. Beachten Sie, dass der gesamte Code hier vollständig ungetestet ist.
Schreiben wir zunächst eine benutzerdefinierte Ausnahme:
Die Ausnahme dient als eine Art DTO zum Transportieren eines Abfrageobjekts, sodass Sie es in einem
catch
Block abrufen und verwenden können.Besser mit Code erklärt:
Dies sollte mehr oder weniger funktionieren, es gibt jedoch viele Hooks, die Sie beispielsweise nicht
"the_posts"
auslösen werden, und vieles mehr. Wenn Sie Code haben, der einen dieser Hooks zum Auslösen verwendet, wird dieser unterbrochen.Sie können die
cached_query_set
Funktion verwenden, um einige der Hooks auszulösen, die Ihr Theme / Plugin möglicherweise benötigt.quelle
do_action
sollte aber imtry
Block sein.Dies ist eine PHP-Frage mehr als eine WordPress-Frage.
Wie @Mark kommentierte:
Das ist wahr. Durch Platzieren
return
in der Funktion wird die Funktion beendet, und durch Platzieren der Rückgabe in einer PHP-Datei wird die Datei beendet. Verwechseln Sie sich nicht mit dem PHP-Konstruktexit()
: P (Möglicherweise finden Sie auf SO eine bessere Antwort zu PHPreturn
).Und um deine Frage zu beantworten
Sie können die Last der Abfrage reduzieren, indem Sie eine einzelne Spalte anstelle der vollständigen Tabelle abrufen. Wie @birgire hier Entfernen Sie die Homepage-Abfrage
Vielleicht ist eine bessere Antwort noch zu kommen. Ich habe gerade das geteilt, was ich weiß :)
quelle
posts_request
Filter neutralisiert haben ? Mit diesem + einspaltigen Ansatz beenden wirWP_Query
früher als mit demposts_pre_query
Filter. Achten Sie auch auf die klebrigen Pfosten mit,posts_pre_query
aber wir können sie mit$q->set( 'ignore_sticky_posts', 1 );
z . B. im Beispiel hier entfernen .posts_pre_query
nicht hilft. Ihre Lösung ist die bisher beste. :) Wenn Sie wissen, wie wir die Abfrage direkt danach beenden könnenpre_get_posts
, könnte das großartig sein. Vielen Dank!posts_pre_query
wird ab 4.6 verfügbar sein;)WP_Query
Klasse mit einer benutzerdefiniertenget_posts()
Methode zu erweitern, die möglicherweise frühzeitig vorhanden ist,parent::get_posts()
und die die entsprechende Abfrage aufruft und damit überschreibt. Aber ich weiß nicht, ob das mit Ihrem Fall hier funktionieren oder Sinn machen würde ;-) @DanDies wird in 4.6 (sofern bis zur Veröffentlichung keine Änderungen vorgenommen wurden) mit dem neuen
posts_pre_query
Filter https://core.trac.wordpress.org/ticket/36687 ermöglichtquelle
Ja, es ist möglich, je nachdem, was Sie zwischenspeichern möchten. Ich habe etwas Ähnliches getan, um die Hauptschleife auf unserer Homepage zwischenzuspeichern. Im Wesentlichen können Sie das
posts_request
und verwendenposts_results
, um die Abfrage zu entführen und stattdessen auf den Cache zuzugreifen, und dann auchfound_posts
, um die Paginierung zu korrigieren.Wirklich grobes Beispiel aus unserem Code (ungetestet), aber Sie sollten Ihnen helfen, die Idee zu bekommen:
Mehr hier: https://www.reddit.com/r/Wordpress/comments/19crcn/best_practice_for_hijacking_main_loop_and_caching/
quelle