I problemi relativi all'impostazione di un parametro di query su un valore inesistente sono 2:
- La query verrà eseguita, quindi anche se sai già che non ci saranno risultati, c'è un piccolo prezzo di rendimento da pagare
- Le query di WordPress hanno 19 diversi
'posts_*'
hook di filtro ( 'posts_where'
, 'post_join'
ecc.) Che agiscono sulla query, quindi non si può mai essere sicuri che anche impostando parametri inesistenti la query non restituisca risultati, una semplice OR
clausola restituita da un filtro fa restituire qualcosa.
Avete bisogno di un po ' hard di routine per essere sicuri di una query restituire alcun risultato e non c'è (o molto minimun) problema di prestazioni.
Per attivare quella routine, è possibile utilizzare ogni metodo, tecnicamente è possibile passare qualsiasi argomento WP_Query
, argomenti evento che non esiste.
Quindi, se ti piace qualcosa del genere 'force_no_results' => true
, puoi usarlo in questo modo:
$a = new WP_Query( array( 's' => 'foo', 'force_no_results' => true ) );
e aggiungi un callback in esecuzione 'pre_get_posts'
che faccia il duro lavoro:
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 );
Ciò che fa questo codice viene eseguito il 'pre_get_posts'
più tardi possibile. Se l'argomento 'force_no_results' è presente nella query, allora:
- rimuovere innanzitutto tutti i possibili filtri che possono interferire con la query e archiviarli in un array di helper
- dopo esserti assicurato che il filtro sia attivato, aggiungi un filtro che restituisca questo tipo di richiesta:
SELECT ID FROM wp_posts WHERE 0 = 1
una volta rimossi tutti i filtri, non c'è possibilità che questa query venga modificata ed è molto veloce e non ha alcun risultato certo
- immediatamente dopo l'esecuzione di questa query, tutti i filtri originali (se presenti) vengono ripristinati e tutte le query successive funzioneranno come previsto.
WP_Query()
di non restituire risultati può o meno essere il modo migliore per rispondere a questa domanda. Potrebbe anche essere utile se descrivi il modello di ricerca che desideri non sia interrogabile. Conoscere il modello di ricerca potrebbe aiutare a scovare una soluzione.