Los problemas al 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, debe pagar un pequeño precio de rendimiento
- Consultas WordPress tiene 19 diferentes
'posts_*'
enlaces de filtros ( 'posts_where'
, 'post_join'
, etc ..) que actúan sobre la consulta, por lo que nunca puede estar seguro de que incluso el establecimiento de parámetro unexistent la consulta devuelve ningún resultado, un simple OR
cláusula devuelto por un filtro devolverlo es algo.
Necesita una rutina un poco dura para asegurarse de que una consulta no devuelva ningún resultado y no haya un problema de rendimiento (o muy mínimo).
Para activar esa rutina, puede usar todos los métodos, técnicamente puede pasar cualquier argumento a WP_Query
, argumentos de evento que no existan.
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 agrega una devolución de llamada en ejecución 'pre_get_posts'
que hace 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 lo 'pre_get_posts'
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 almacénelos dentro de una matriz auxiliar
- después de asegurarse de que se activa el filtro, agregue un filtro que devuelva 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 es muy rápida, y no tiene ningún resultado seguro
- inmediatamente después de ejecutar esta consulta, todos los filtros originales (si los hubiera) se restauran y todas las consultas posteriores funcionarán como se esperaba.
WP_Query()
no devolver resultados puede o no ser la mejor manera de responder a esa pregunta. También podría ser útil si describiera el patrón de búsqueda que desea que no se pueda consultar. Conocer el patrón de búsqueda podría ayudar a descubrir una solución.