Có vẻ như một nửa các hướng dẫn trong Codex và xung quanh việc sử dụng blog query_posts()
và sử dụng một nửa WP_Query
. Thỏa thuận là gì?
Có vẻ như một nửa các hướng dẫn trong Codex và xung quanh việc sử dụng blog query_posts()
và sử dụng một nửa WP_Query
. Thỏa thuận là gì?
Câu trả lời:
query_posts()
quá đơn giản và là một cách có vấn đề để sửa đổi truy vấn chính của trang bằng cách thay thế nó bằng phiên bản mới của truy vấn. Đó là không hiệu quả (chạy lại các truy vấn SQL) và sẽ hoàn toàn thất bại trong một số trường hợp (đặc biệt là thường xuyên khi xử lý phân trang bài viết). Bất kỳ mã WP hiện đại nào cũng nên sử dụng các phương thức đáng tin cậy hơn, như sử dụng pre_get_posts
hook, cho mục đích này. TL; DR không sử dụng query_posts () bao giờ .
get_posts()
sử dụng rất giống nhau và chấp nhận cùng một đối số (với một số sắc thái, như các mặc định khác nhau), nhưng trả về một loạt các bài đăng, không sửa đổi các biến toàn cục và an toàn để sử dụng ở bất cứ đâu.
WP_Query
là lớp cung cấp năng lượng cho cả hai phía sau hậu trường, nhưng bạn cũng có thể tạo và làm việc với thể hiện của chính nó. Một chút phức tạp hơn, ít hạn chế hơn, cũng an toàn để sử dụng ở bất cứ đâu.
query_posts()
là chức năng bao bọc nhỏ bé WP_Query
, điều duy nhất bổ sung (theo lưu đồ) là ghi đè toàn cầu$wp_query
query_posts()
bằng WP_Query
sẽ không có sự khác biệt về hiệu suất, truy vấn của trang gốc vẫn sẽ chạy vì đó là một phần của tải trọng cốt lõi. Các truy vấn đó sẽ chạy ngay cả khi tệp mẫu của bạn không có vòng lặp nào cả.
query_posts
hoàn toàn không sửa đổi vòng lặp chính, nó sẽ thay thế nó sau khi nó đã chạy. Cách tốt nhất để sửa đổi vòng lặp chính là thông qua pre_get_posts
bộ lọc. developer.wordpress.com/2012/05/14/NH
query_posts
- Bạn không bao giờ nên sử dụng query_posts
. Ngoài những gì @Rarst đã nói, vấn đề thực sự lớn query_posts
là, nó phá vỡ đối tượng truy vấn chính (được lưu trữ trong $wp_query
). Rất nhiều plugin và mã tùy chỉnh phụ thuộc vào đối tượng truy vấn chính, do đó, việc phá vỡ đối tượng truy vấn chính có nghĩa là bạn đang phá vỡ các chức năng của plugin và mã tùy chỉnh. Chỉ cần một chức năng như vậy là tất cả chức năng phân trang quan trọng, vì vậy nếu bạn phá vỡ truy vấn chính, bạn sẽ phá vỡ phân trang.
Để chứng minh mức độ xấu của query_posts
nó, trên bất kỳ mẫu nào, hãy làm như sau và so sánh kết quả
var_dump( $wp_query );
query_posts( '&posts_per_page=-1' );
var_dump( $wp_query );
get_posts
và WP_Query
là cách chính xác để xây dựng các truy vấn thứ cấp ( như các bài đăng liên quan, thanh trượt, nội dung nổi bật và nội dung trên các trang đầu tĩnh ) với. Cần lưu ý, bạn không nên sử dụng bất kỳ một trong hai ưu tiên cho truy vấn chính trên trang chủ, trang đơn hoặc bất kỳ loại trang lưu trữ nào vì nó sẽ phá vỡ chức năng của trang. Nếu bạn cần sửa đổi truy vấn chính, hãy sử dụng pre_get_posts
để làm như vậy và không phải là truy vấn tùy chỉnh. ( CẬP NHẬT: Đối với trang trước tĩnh và trang thật, hãy xem Sử dụng pre_get_posts trên trang thật và trang trước tĩnh *)
Về bản chất, WP_Query
được sử dụng bởi truy vấn chính và cũng được sử dụng bởi get_posts
, nhưng mặc dù get_posts()
sử dụng WP_Query
, có một vài khác biệt
get_posts
là nhanh hơn WP_Query
. Biên độ phụ thuộc vào số lượng tổng số bài viết của trang web. Lý do cho điều này là, get_posts
đi 'no_found_rows' => true
theo mặc định để WP_Query
mà bỏ qua / hợp pháp phá vỡ pagination. Với 'no_found_rows' => true
, WP_Query
nhận được số lượng bài đăng được truy vấn, sau đó giải cứu, theo mặc định, nó sẽ tìm kiếm thêm tất cả các bài đăng phù hợp với truy vấn để tính toán phân trang.
Vì lý do này, get_posts()
chỉ nên được sử dụng cho các truy vấn không phân trang. Pagination get_posts
thực sự là một mớ hỗn độn lớn. WP_Query
nên được sử dụng cho tất cả các truy vấn phân trang
get_posts()
không bị ảnh hưởng bởi các posts_*
bộ lọc WP_Query
bị ảnh hưởng bởi các bộ lọc này. Lý do là get_posts
, theo mặc định, chuyển 'suppress_filters' => true
đếnWP_Query
get_posts
có một vài tham số bổ sung như include
, exclude
, numberposts
và category
. Các tham số này được thay đổi thành các tham số hợp lệ cho WP_Query
trước khi được chuyển đến WP_Query
. include
được thay đổi thành post__in
, exclude
thành post__not_in
, category
vào cat
và numberposts
vào posts_per_page
. Chỉ cần một lưu ý, tất cả các tham số có thể được chuyển qua để WP_Query
làm việc với get_posts
, bạn có thể bỏ qua và không sử dụng các tham số mặc định củaget_posts
get_posts
chỉ trả về thuộc $posts
tính WP_Query
trong khi WP_Query
trả về đối tượng hoàn chỉnh. Đối tượng này khá hữu ích khi nói đến điều kiện, phân trang và thông tin hữu ích khác có thể được sử dụng bên trong vòng lặp.
get_posts
không sử dụng vòng lặp, nhưng foreach
vòng lặp để hiển thị bài viết. Ngoài ra, không có thẻ mẫu có sẵn theo mặc định. setup_postdata( $post )
phải được sử dụng để làm cho các thẻ mẫu có sẵn. WP_Query
sử dụng các thẻ vòng lặp và mẫu có sẵn theo mặc định
get_posts
đi 'ignore_sticky_posts' => 1
tới WP_Query
, vì vậy get_posts
theo mặc định bỏ qua bài viết dính
Dựa trên những điều trên, việc sử dụng get_posts
hay WP_Query
tùy thuộc vào bạn và bạn thực sự cần gì từ truy vấn. Ở trên sẽ hướng dẫn bạn trong sự lựa chọn của bạn
Sự khác biệt cơ bản query_posts()
là thực sự chỉ để sửa đổi Loop hiện tại. Khi bạn đã hoàn tất, cần phải thiết lập lại vòng lặp và gửi nó theo cách vui vẻ. Phương pháp này cũng dễ hiểu hơn một chút, đơn giản vì "truy vấn" của bạn về cơ bản là một chuỗi URL mà bạn chuyển đến hàm, như vậy:
query_posts('meta_key=color&meta_value=blue');
Mặt khác, WP_Query
là một công cụ có mục đích chung hơn, và giống như trực tiếp viết các truy vấn MySQL hơn query_posts()
là. Bạn cũng có thể sử dụng nó ở bất cứ đâu (không chỉ trong Vòng lặp) và nó không can thiệp vào bất kỳ truy vấn bài đang chạy nào.
Tôi có xu hướng sử dụng WP_Query
thường xuyên hơn, như nó xảy ra. Thực sự, nó sẽ đi vào trường hợp cụ thể của bạn.
Đơn giản là không cần sử dụng query_posts()
. Tất cả những gì nó làm là khởi tạo một đối tượng WP_Query mới và gán lại đối tượng mới đó global wp_query
.
Để tham khảo, sau đây là query_posts()
chức năng thực tế .
function query_posts($query) {
$GLOBALS['wp_query'] = new WP_Query();
return $GLOBALS['wp_query']->query($query);
}
Khởi tạo đối tượng WP_Query của riêng bạn nếu bạn muốn tạo một tập lệnh truy vấn tùy chỉnh chuyên sâu. Hoặc sử dụng get_posts()
nếu tất cả những gì bạn cần làm là một số thao tác nhẹ ở đây và đó.
Trong cả hai trường hợp, tôi đặc biệt khuyên bạn nên tự mình làm và tiếp tục wp_includes/query.php
và tìm hiểu kỹ về WP_Query
lớp học.
Đảm bảo rằng bạn sử dụng wp_reset_query()
sau khi sử dụng query_posts()
vì nó cũng sẽ ảnh hưởng đến kết quả truy vấn khác.