Os problemas ao definir um parâmetro de consulta para um valor inexistente são 2:
- A consulta será executada. Portanto, mesmo se você já souber que não haverá resultados, há um pequeno preço de desempenho a pagar
- As consultas do WordPress têm 19
'posts_*'
ganchos de filtro diferentes ( 'posts_where'
, 'post_join'
etc.) que atuam na consulta, para que você nunca tenha certeza de que, mesmo definindo parâmetros inexistentes, a consulta não retorne resultados, uma simples OR
cláusula retornada por um filtro faz com que retorne algo.
Você precisa de uma rotina um pouco incondicional para garantir que uma consulta não retorne resultado e que não haja problema de desempenho (ou muito mínimo).
Para acionar essa rotina, você pode usar todos os métodos, tecnicamente pode passar qualquer argumento para WP_Query
, argumentos de evento que não existem.
Então, se você gosta de algo assim 'force_no_results' => true
, pode usá-lo da seguinte maneira:
$a = new WP_Query( array( 's' => 'foo', 'force_no_results' => true ) );
e adicione um retorno de chamada em execução 'pre_get_posts'
que faça o trabalho duro:
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 );
O que esse código faz é executado o 'pre_get_posts'
mais tarde possível. Se o argumento 'force_no_results' estiver presente na consulta, então:
- primeiro remova todos os filtros possíveis que possam interferir na consulta e armazene-os em uma matriz auxiliar
- depois de ter certeza de que o filtro foi acionado, filtro adda que retorna esse tipo de solicitação:
SELECT ID FROM wp_posts WHERE 0 = 1
depois que todos os filtros são removidos, não há possibilidade de que essa consulta seja alterada e seja muito rápida e sem resultados.
- imediatamente após a execução dessa consulta, todos os filtros originais (se houver) são restaurados e todas as consultas subseqüentes funcionarão conforme o esperado.
WP_Query()
retorno de nenhum resultado pode ou não ser a melhor maneira de responder a essa pergunta. Também pode ser útil se você descrever o padrão de pesquisa que deseja ser inquestionável. Conhecer o padrão de pesquisa pode ajudar a encontrar uma solução.