Bir sorgu parametresini var olmayan değere ayarlamadaki sorunlar 2'dir:
- Sorgu çalışır, bu nedenle zaten bir sonuç olmayacağını bilseniz bile, ödenecek küçük bir performans fiyatı vardır
- WordPress sorgularında, sorguya etki eden 19 farklı
'posts_*'
filtre kancası ( 'posts_where'
,, 'post_join'
vb ..) vardır, bu nedenle, varolmayan bir param sorgusunun sonuç döndürmeyeceğinden, OR
bir filtre tarafından döndürülen basit bir cümlenin bir şey döndürdüğünden asla emin olamazsınız .
Bir sorgunun sonuç döndürmediğinden ve hiçbir (veya çok küçük) performans sorunu olmadığından emin olmak için biraz zorlayıcı rutine ihtiyacınız var.
Bu rutini tetiklemek için her yöntemi kullanabilirsiniz, teknik olarak herhangi bir argümanı WP_Query
, var olmayan olay argümanlarını iletebilirsiniz .
Öyleyse 'force_no_results' => true
, onun gibi bir şeyi seviyorsanız , onun gibi kullanabilirsiniz:
$a = new WP_Query( array( 's' => 'foo', 'force_no_results' => true ) );
ve 'pre_get_posts'
zor iş yapan bir geri arama çalıştırarak ekleyin :
add_action( 'pre_get_posts', function( $q ) {
if (array_key_exists('force_no_results', $q->query) && $q->query['force_no_results']) {
$q->query = $q->query_vars = array();
$added = array();
$filters = array(
'where', 'where_paged', 'join', 'join_paged', 'groupby', 'orderby', 'distinct',
'limits', 'fields', 'request', 'clauses', 'where_request', 'groupby_request',
'join_request', 'orderby_request', 'distinct_request','fields_request',
'limits_request', 'clauses_request'
);
// remove all possible interfering filter and save for later restore
foreach ( $filters as $f ) {
if ( isset($GLOBALS['wp_filter']["posts_{$f}"]) ) {
$added["posts_{$f}"] = $GLOBALS['wp_filter']["posts_{$f}"];
unset($GLOBALS['wp_filter']["posts_{$f}"]);
}
}
// be sure filters are not suppressed
$q->set( 'suppress_filters', FALSE );
$done = 0;
// use a filter to return a non-sense request
add_filter('posts_request', function( $r ) use( &$done ) {
if ( $done === 0 ) { $done = 1;
$r = "SELECT ID FROM {$GLOBALS['wpdb']->posts} WHERE 0 = 1";
}
return $r;
});
// restore any filter that was added and we removed
add_filter('posts_results', function( $posts ) use( &$done, $added ) {
if ( $done === 1 ) { $done = 2;
foreach ( $added as $hook => $filters ) {
$GLOBALS['wp_filter'][$hook] = $filters;
}
}
return $posts;
});
}
}, PHP_INT_MAX );
Bu kodun yaptığı 'pre_get_posts'
mümkün olduğunca geç çalıştırılıyor . Sorguda 'force_no_results' argümanı varsa, o zaman:
- önce sorguyu engelleyebilecek tüm olası filtreleri kaldırın ve bunları bir yardımcı dizi içinde saklayın
- Filtrenin tetiklendiğinden emin olduktan sonra, bu tür bir istek döndüren adda filtresi:
SELECT ID FROM wp_posts WHERE 0 = 1
bütün filtreler kaldırıldıktan sonra, bu sorgu değiştirilemez ve çok hızlıdır ve kesin bir sonucu yoktur.
- Bu sorgu çalıştırıldıktan hemen sonra, tüm orijinal filtreler (varsa) geri yüklenir ve izleyen tüm sorgular beklendiği gibi çalışır.
WP_Query()
hiçbir sonuç döndürmesi veya bu soruyu cevaplamanın en iyi yolu olabilir veya olmayabilir. Eğer olsaydı Ayrıca yararlı olabilir arama deseni tanımlamak size unqueryable olmak istediğini. Arama modelini bilmek bir çözümün ortaya çıkmasına yardımcı olabilir.