Проблемы с установкой для параметра запроса несуществующего значения: 2:
- Запрос будет выполнен, поэтому, даже если вы уже знаете, что результатов не будет, придется заплатить небольшую цену за производительность.
- Запросы WordPress имеют 19 различных
'posts_*'
хуков фильтров ( 'posts_where'
, 'post_join'
и т. Д.), Которые действуют на запрос, поэтому вы никогда не можете быть уверены, что даже если задать несуществующий параметр, запрос не даст результатов, простое OR
предложение, возвращаемое фильтром, возвращает что-то.
Вам нужно немного жесткой подпрограммы, чтобы убедиться, что запрос не даст результата, и нет проблем с производительностью (или очень незначительных).
Чтобы запустить эту подпрограмму, вы можете использовать каждый метод, технически вы можете передать любой аргумент WP_Query
, аргументы события, которые не существуют.
Так что если вам нравится что-то вроде 'force_no_results' => true
, вы можете использовать это так:
$a = new WP_Query( array( 's' => 'foo', 'force_no_results' => true ) );
и добавьте обратный вызов 'pre_get_posts'
, выполняющий тяжелую работу:
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 );
Этот код запускается 'pre_get_posts'
как можно позже. Если в запросе присутствует аргумент force_no_results, то:
- сначала удалите все возможные фильтры, которые могут помешать выполнению запроса, и сохраните их внутри вспомогательного массива.
- После того, как убедитесь, что фильтр запущен, добавьте фильтр, который возвращает этот вид запроса:
SELECT ID FROM wp_posts WHERE 0 = 1
после того, как все фильтры удалены, нет возможности изменить этот запрос, и он очень быстрый и не дает никакого результата наверняка.
- сразу после выполнения этого запроса все исходные фильтры (если они были) восстанавливаются, и все последующие запросы будут работать как положено.
WP_Query()
возврата результатов не может или не может быть лучшим способом ответить на этот вопрос. Также было бы полезно, если бы вы описали шаблон поиска, который вы хотите сделать незапрашиваемым. Знание шаблона поиска может помочь найти решение.