Los problemas en establecer un parámetro de consulta en un valor inexistente son 2:
- La consulta se ejecutará, por lo que incluso si ya sabe que no habrá resultados, hay un pequeño precio de rendimiento que pagar
- Las consultas de WordPress tienen 19 ganchos de filtro
'posts_*'
diferentes ( 'posts_where'
, 'post_join'
, etc.) que actúan sobre la consulta, por lo que nunca se puede estar seguro de que, al establecer un parámetro inexistente, la consulta no arroje resultados, una simple La cláusula OR
devuelta por un filtro hace devolver algo.
Necesitas un poco de rutina hardcore para estar seguro de que la consulta no produce ningún resultado y no hay ningún problema de rendimiento (o muy mínimo).
Para activar esa rutina, puedes usar todos los métodos, técnicamente puedes pasar cualquier argumento a WP_Query
, argumentos de evento que no existen.
Entonces, si te gusta algo como 'force_no_results' => true
, puedes usarlo así:
$a = new WP_Query( array( 's' => 'foo', 'force_no_results' => true ) );
y agregue una devolución de llamada que se ejecute en 'pre_get_posts'
que haga el trabajo 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 );
Lo que hace este código se ejecuta en 'pre_get_posts'
lo más tarde posible. Si el argumento 'force_no_results' está presente en la consulta, entonces:
- primero elimine todos los filtros posibles que puedan interferir con la consulta y guárdelos dentro de una matriz de ayuda
- después de asegurarse de que se active el filtro, el filtro adda que devuelve este tipo de solicitud:
SELECT ID FROM wp_posts WHERE 0 = 1
una vez que se eliminan todos los filtros, no hay posibilidades de que esta consulta cambie y sea muy rápida, y no tiene ningún resultado seguro / li>
- inmediatamente después de ejecutar esta consulta, todos los filtros originales (si hubiera alguno) se restaurarán y todas las consultas posteriores funcionarán como se esperaba.