Les problèmes liés à la définition d'un paramètre de requête sur une valeur inexistante sont 2:
- La requête s'exécutera, donc même si vous savez déjà qu'il n'y aura aucun résultat, il y a un petit prix de performance à payer
- Requêtes WordPress a 19 différents
'posts_*'
crochets de filtre ( 'posts_where'
, 'post_join'
, etc ..) qui agissent sur requête, de sorte que vous ne pouvez jamais être sûr que même la mise en unexistent param la requête ne renvoie aucun résultat, un simple OR
article retourné par un filtre quelque chose faire de retour.
Vous avez besoin d'un peu de routine hardcore pour être sûr qu'une requête ne renvoie aucun résultat et qu'il n'y a pas de problème de performance (ou très minimun).
Pour déclencher cette routine, vous pouvez utiliser toutes les méthodes, techniquement vous pouvez passer n'importe quel argument à des arguments d' WP_Query
événement qui n'existent pas.
Donc, si vous aimez quelque chose comme ça 'force_no_results' => true
, vous pouvez l'utiliser comme ceci:
$a = new WP_Query( array( 's' => 'foo', 'force_no_results' => true ) );
et ajoutez un rappel en cours d'exécution 'pre_get_posts'
qui fait le travail dur:
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 );
Ce que fait ce code est exécuté le 'pre_get_posts'
plus tard possible. Si l'argument 'force_no_results' est présent dans la requête, alors:
- supprimez d'abord tous les filtres possibles susceptibles d'interférer avec la requête, puis stockez-les dans un tableau d'aide
- après avoir vérifié que le filtre est déclenché, ajoutez un filtre qui retourne ce genre de requête:
SELECT ID FROM wp_posts WHERE 0 = 1
une fois tous les filtres supprimés, il n'y a aucune possibilité que cette requête soit modifiée et elle est très rapide, et n'a aucun résultat sûr
- immédiatement après l'exécution de cette requête, tous les filtres d'origine (le cas échéant) sont restaurés et toutes les requêtes suivantes fonctionnent comme prévu.
WP_Query()
de ne retourner aucun résultat peut ou non être la meilleure façon de répondre à cette question. Il pourrait également être utile de décrire le modèle de recherche que vous souhaitez rendre impossible à interroger. Connaître le modèle de recherche pourrait aider à trouver une solution.