Các vấn đề về đặt tham số truy vấn thành giá trị không tồn tại là 2:
- Truy vấn sẽ chạy, vì vậy ngay cả khi bạn đã biết sẽ không có kết quả, vẫn có một giá thực hiện nhỏ phải trả
- Các truy vấn WordPress có 19
'posts_*'
móc lọc khác nhau ( 'posts_where'
,, 'post_join'
v.v.) hoạt động theo truy vấn, do đó bạn không bao giờ có thể chắc chắn rằng ngay cả việc đặt tham số không tồn tại, truy vấn không trả về kết quả, một OR
mệnh đề đơn giản được bộ lọc trả về sẽ trả về một cái gì đó.
Bạn cần một chút Hardcore thường xuyên để được chắc chắn một truy vấn trở lại không có kết quả và không có (hoặc rất minimun) vấn đề hiệu suất.
Để kích hoạt thói quen đó, bạn có thể sử dụng mọi phương thức, về mặt kỹ thuật bạn có thể chuyển bất kỳ đối số nào cho các đối số WP_Query
sự kiện không tồn tại.
Vì vậy, nếu bạn thích một cái gì đó như 'force_no_results' => true
, bạn có thể sử dụng nó như vậy:
$a = new WP_Query( array( 's' => 'foo', 'force_no_results' => true ) );
và thêm một cuộc gọi lại chạy trên 'pre_get_posts'
đó làm công việc khó khăn:
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 );
Những gì mã này làm là chạy 'pre_get_posts'
càng muộn càng tốt. Nếu đối số 'force_no_results' xuất hiện trong truy vấn, thì:
- trước tiên hãy xóa tất cả các bộ lọc có thể có thể can thiệp vào truy vấn và lưu trữ chúng bên trong một mảng trợ giúp
- sau khi chắc chắn bộ lọc được kích hoạt, bộ lọc adda trả về loại yêu cầu này:
SELECT ID FROM wp_posts WHERE 0 = 1
một khi tất cả các bộ lọc bị xóa, không có khả năng truy vấn này bị thay đổi và nó rất nhanh và không có kết quả chắc chắn
- ngay sau khi truy vấn này được chạy, tất cả các bộ lọc ban đầu (nếu có) được khôi phục và tất cả các truy vấn tiếp theo sẽ hoạt động như mong đợi.
WP_Query()
trả về không có kết quả có thể hoặc không phải là cách tốt nhất để trả lời câu hỏi đó. Nó cũng có thể hữu ích nếu bạn mô tả mẫu tìm kiếm mà bạn muốn không cần thiết. Biết mô hình tìm kiếm có thể giúp tìm ra giải pháp.