Masalah pada menetapkan parameter kueri ke nilai tidak ada adalah 2:
- Kueri akan berjalan, jadi meskipun Anda sudah tahu tidak akan ada hasil, ada sedikit harga kinerja yang harus dibayar
- Kueri WordPress memiliki 19
'posts_*'
kait filter yang berbeda ( 'posts_where'
,, 'post_join'
dll.) Yang berfungsi pada kueri, sehingga Anda tidak pernah dapat memastikan bahwa bahkan pengaturan param yang tidak ada, kueri tidak menghasilkan apa-apa, OR
klausa sederhana yang dikembalikan oleh filter membuat sesuatu kembali.
Anda perlu sedikit rutin hardcore untuk memastikan kueri kembali tanpa hasil dan tidak ada (atau sangat minim) masalah kinerja.
Untuk memicu rutinitas itu, Anda bisa menggunakan setiap metode, secara teknis Anda bisa meneruskan argumen apa pun WP_Query
, argumen peristiwa yang tidak ada.
Jadi, jika Anda menyukai sesuatu seperti 'force_no_results' => true
, Anda dapat menggunakannya seperti ini:
$a = new WP_Query( array( 's' => 'foo', 'force_no_results' => true ) );
dan menambahkan callback yang berjalan pada 'pre_get_posts'
yang melakukan kerja keras:
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 );
Apa yang dilakukan kode ini dijalankan 'pre_get_posts'
selambat mungkin. Jika argumen 'force_no_results' hadir dalam kueri, maka:
- pertama-tama hapus semua kemungkinan filter yang dapat mengganggu kueri, dan simpan di dalam array pembantu
- setelah yakin bahwa filter terpicu, tambahkan filter yang mengembalikan permintaan semacam ini:
SELECT ID FROM wp_posts WHERE 0 = 1
begitu semua filter dihapus, tidak ada kemungkinan permintaan ini diubah dan sangat cepat, dan tidak memiliki hasil pasti
- segera setelah kueri ini dijalankan, semua filter asli (jika ada) dipulihkan dan semua kueri berikutnya akan berfungsi seperti yang diharapkan.
WP_Query()
tidak ada hasil mungkin atau mungkin bukan cara terbaik untuk menjawab pertanyaan itu. Mungkin juga bermanfaat jika Anda menggambarkan pola pencarian yang Anda inginkan tidak dapat ditanyakan. Mengetahui pola pencarian mungkin membantu menemukan solusi.