Hiện tại, điều đó là không thể.
Khi 'pre_get_posts'
chạy, quá muộn để dừng lại WP_Query
để thực hiện một truy vấn.
Bản thân WordPress, khi bạn cố gắng truy vấn một nguyên tắc phân loại không tồn tại, sẽ thêm AND (0 = 1)
vào WHERE
mệnh đề của truy vấn SQL, để đảm bảo nó không trả về kết quả nhanh chóng ...
Có một vé trac với một bản vá có thể sẽ rơi vào cốt lõi với WP 4.6, giới thiệu một bộ lọc mới : 'posts_pre_query'
. Trả về một mảng trên bộ lọc đó sẽ khiến việc WP_Query
dừng xử lý và sử dụng mảng được cung cấp như mảng bài viết của nó.
Điều này bằng cách nào đó có thể giúp bạn trong việc thực hiện những gì bạn đang cố gắng làm.
Chờ đợi điều này, bất cứ điều gì bạn có thể làm là bằng cách nào đó hackish , bản thân lõi lừa sử dụng cũng khá hackish.
Gần đây, tôi bắt đầu sử dụng một mẹo khi tôi muốn dừng WordPress để làm những việc mà tôi không thể dừng lại một cách sạch sẽ: Tôi ném một ngoại lệ và bắt nó để tiếp tục dòng ứng dụng.
Tôi sẽ chỉ cho bạn một ví dụ. Lưu ý tất cả các mã ở đây là hoàn toàn chưa được kiểm tra.
Trước hết, hãy viết một ngoại lệ tùy chỉnh:
class My_StopWpQueryException extends Exception {
private $query;
public static forQuery(WP_Query $query) {
$instance = new static();
$instance->query = $query;
return $instance;
}
public function wpQuery() {
return $this->query;
}
}
Ngoại lệ được thiết kế để hoạt động như một loại DTO để vận chuyển một đối tượng truy vấn, để trong một catch
khối bạn có thể lấy và sử dụng nó.
Giải thích rõ hơn với mã:
function maybe_cached_query(WP_Query $query) {
$cached_query = wp_cache_get($query->query_vars_hash, 'globals');
if ($cached_query instanceof WP_Query)
throw My_StopWpQueryException::forQuery($cached_query);
}
function cached_query_set(WP_Query $query) {
$GLOBALS['wp_query'] = $query;
$GLOBALS['wp_the_query'] = $query;
// maybe some more fine-tuning here...
}
add_action('pre_get_posts', function(WP_Query $query) {
if ($query->is_main_query() && ! is_admin()) {
try {
maybe_cached_query($query);
} catch(My_StopWpQueryException $e) {
cached_query_set($e->wpQuery());
}
}
});
Điều này sẽ ít nhiều hoạt động, tuy nhiên, có rất nhiều hook mà bạn sẽ không kích hoạt, ví dụ "the_posts"
và nhiều hơn nữa ... nếu bạn có mã sử dụng một trong những hook đó để kích hoạt, nó sẽ bị hỏng.
Bạn có thể sử dụng cached_query_set
chức năng để bắn một số móc mà chủ đề / plugin của bạn có thể yêu cầu.