---
description: https://lamvt.vn/khi-nao-thi-nen-su-dung-wp_query-query_posts-va-get_posts/
---

# Khi nào thì dùng WP\_Query (), query\_posts () và pre\_get\_posts phần 2 (ok)

## Khi nào nên sử dụng WP\_Query, query\_posts() và get\_posts()?

&#x20;[Nguyễn Phương Linh](https://lamvt.vn/author/phuonglinhqc/) [ Tháng Mười 27, 2018](https://lamvt.vn/khi-nao-thi-nen-su-dung-wp_query-query_posts-va-get_posts/)  [Hướng dẫn học WordPress](https://lamvt.vn/category/huong-dan-hoc-wordpress/)  803 Lượt xem**5** / **5** ( **2** bình chọn )

Có vẻ như một nửa số hướng dẫn trong Codex và cộng đồng viết blog (blogosphere) sử dụng query\_posts() và nửa số còn lại sử dụng WP\_Query. Vấn đề ở đây là gì?

[![Khi nào nên sử dụng WP\_Query, query\_posts() và get\_posts()? Blog\_Tool\_\_Publishing\_Platform\_\_and\_CMS\_WordPress](https://lamvt.vn/wp-content/uploads/2018/10/Blog_Tool__Publishing_Platform__and_CMS_WordPress.png)](https://lamvt.vn/wp-content/uploads/2018/10/Blog_Tool__Publishing_Platform__and_CMS_WordPress.png)

Xem qua cái này longer analysis – prosti Dec 25 ’16 at 23:26

### 8 câu trả lời

#### Câu trả lời chính xác nhất

* query\_posts() là cách cực kỳ đơn giản và hay xảy ra nhiều vấn đề dùng để sửa truy vấn chính của một trang bằng cách thay thế nó bởi ví dụ truy vấn mới. Nó không hiệu quả (re-runs SQL queries) và sẽ hoàn toàn thất bại trong một số trường hợp (đặc biệt là khi làm việc với các bài viết có đánh số trang). Bất kì WP code hiện đại nào cũng sử dụng nhiều phương pháp đáng tin cậy hơn, như việc tận 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() rất giống trong sử dụng và nó chấp nhận các đối số giống nhau (với một số sắc thái, như các giá trị mặc định khác nhau), nhưng nó trả về một loạt các bài viết, các biến số toàn cục (global variable) không bị sửa đổi và nó an toàn khi sử dụng ở bất cứ đâu;
* WP\_query có sức mạnh cả phía sau hậu trường, nhưng bạn cũng có thể tạo và làm việc với đối tượng riêng của nó. Nó phức tạp hơn một chút, nhưng ít giới hạn hơn, và cũng an toàn để sử dụng ở bất cứ đâu.

![Khi nào nên sử dụng WP\_Query, query\_posts() và get\_posts()? khi-nao-thi-nen-su-dung-wp\_query-query\_posts-va-get\_posts-1](https://lamvt.vn/wp-content/uploads/2018/10/khi-nao-thi-nen-su-dung-wp_query-query_posts-va-get_posts-1.png)

**Trả lời bởi Rarst**

@jjeaton query\_posts() là chức năng bao hàm nhỏ (wrapper function) cho WP\_Query, điều duy nhất nó có thêm (theo sơ đồ) là overwriting global $wp\_query – Rarst Aug 8 ’11 at 15:39

@jjeaton thay query\_posts() bằng WP\_Query thì hiệu suất sẽ không khác nhau, truy vấn của trang gốc sẽ vẫn chạy bởi vì đó là một phần của core load. Những truy vấn này vẫn sẽ chạy thậm chí nếu tệp mẫu của bạn không có vòng lặp nào. – Rarst Aug 8 ’11 at 17:15

Tôi có cảm giác rằng đây là bài viết xuất sắc và được ủng hộ nhiều nhất trên WPSE. Có lẽ là ở trong Codex nữa. – kaiser♦ Sep 16 ’11 at 0:03&#x20;

Tôi chỉ muốn thêm vào mô tả rõ nhất của tôi về vấn đề “hiệu suất của query\_posts()”: Việc sử dụng query\_posts() hay WP\_Query trong một tệp mẫu có chi phí hiệu suất (performnace cost) giống nhau: Đó là truy vấn bạn vừa thực hiện. Vấn đề được thảo luận trong bài viết codex đó là nếu chính xác bạn muốn thay thế truy vấn thì nên lọc query\_posts() gốc bằng bộ lọc ‘parse\_query’. Với cách này, bạn chỉ có duy nhất một truy vấn gốc mong muốn, thay vì làm một truy vấn thứ hai để rồi lại thay thế nó một cách khó khăn. query\_posts() không bao giờ là cách giải quyết cho vấn đề này – jerclarke Apr 19 ’12 at 22:24

Có một cách giải thích cực kì tuyệt vời về query\_posts được viết bởi John James Jacoby trong blog developer.wordpress.com, nó hơn xa các câu trả lời này. Điểm chính ở đây là: query\_posts không hề sửa đổi vòng lặp chính, nó thay thế chính nó sau khi đã chạy xong. Cách tốt nhất để sửa đổi vòng lặp chính đó là sử dụng bộ lọc pre\_get\_posts. developer.wordpress.com/2012/05/14/… – Dan Gayle Jun 9 ’12 at 23:10

#### Câu trả lời có 51 bình chọn

query\_posts – Bạn đừng bao giờ dùng query\_posts. Ngoại trừ những gì mà @Rarst đã nói, vấn đề lớn nhất của query\_posts là nó phá vỡ đối tượng truy vấn chính (main query object) (được lưu trữ trong $wp\_query). Nhiều plugin và mã tùy chỉnh (custom code) phụ thuộc vào đối tượng truy vấn chính (main query object), vì vậy 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 (custom code). Lấy ví dụ một chức năng rất quan trọng là chức năng đánh số trang, vì vậy nếu bạn phá vỡ truy vấn chính thì bạn sẽ phá vỡ chức năng đánh số trang.

Để chứng minh query\_posts tệ như thế nào, hãy thử như dưới đây với một số mẫu 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à những hướng đi đúng nhất để xây dựng các truy vấn phụ (**secondary** queries) (ví dụ như bài đăng liên quan, các thanh trượt, nội dung nổi bật). Cần lưu ý rằng bạn không nên dùng cái có lợi cho truy vấn chính trên trang chủ, trang riêng lẻ hay bất cứ loại trang lưu trữ nào, bởi vì nó sẽ phá vỡ chức năng của trang. Nếu bạn cần chỉnh sửa truy vấn chính, hãy sử dụng pre\_get\_posts thay vì một truy vấn tùy chỉnh (custom query). Đối với các trang tĩnh và trang thực, hãy xem Using pre\_get\_posts on true pages and static front pages

Về bản chất, WP\_Query được dùng bởi truy vấn chính và cả get\_posts, nhưng mặc dù get\_posts() sử dụng WP\_Query, vẫn có một vài điểm khác nhau như sau:

* get\_posts nhanh hơn WP\_Query. Nó phụ thuộc vào tổng số trang của trang web. Lý do của việc này là get\_posts chuyển _‘no\_found\_rows’ => true_ theo mặc định thành WP\_Query, nó bỏ qua hoặc phân tách việc phân trang. Với _‘no\_found\_rows’ => true,_ theo những gì đã được mặc định WP\_Query có các bài viết đã được truy vấn và sau đó dừng lại để tiếp tục tìm kiếm tất cả các bài viết phù hợp với truy vấn để tính toán phân trang. Vì lý do này, chỉ nên dùng get\_posts với những truy vấn không đánh trang. Việc đánh trang get\_posts thực sự sẽ gây lộn xộn. WP\_Query nên được dùng cho tất cả các truy vấn được phân trang.
* get\_posts không bị ảnh hưởng bởi các bộ lọc _posts\_\*_ trong khi WP\_Query thì bị ảnh hưởng bởi các bộ lọc này. Lý do là get\_posts chuyển _‘no\_found\_rows’ => true_ theo mặc định thành WP\_Query.
* get\_posts có một số thông số bổ sung như _include_, _exclude_, _numberposts_ và _category._ Những tham số này được thay đổi thành các tham số hợp lệ dành cho WP\_Query trước khi được chuyển đến WP\_Query. _include_ được chuyển thành _post\_\_in_, _exclude_ thành _post\_\_not\_in_, _category_ thành _cat_ and _numberposts_ thành _posts\_per\_page._ Chỉ có một lưu ý là, tất cả các tham số mà có thể chuyển sang WP\_Query đều làm việc với get\_posts. Bạn có thể không cần quan tâm tới và không sử dụng các thông số mặc định của get\_posts.
* get\_posts chỉ trả về thuộc tính _$posts_ của 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 làm việc với các điều kiện, đánh số trang và các thông tin hữu ích khác có thể được sử dụng trong vòng lặp.
* get\_posts không sử dụng vòng lặp, thay vào đó là vòng lặp _foreach_ để hiện thị các bài viết. Cũng không có thẻ mẫu nào (template tag) khả dụng theo mặc định. _setup\_postdata( $post )_ được sử dụng để làm cho các thẻ mẫu (template tag) trở nên khả dụng. WP\_Query sử dụng vòng lặp và các thẻ mẫu mặc định sẵn có.
* get\_posts chuyển _‘ignore\_sticky\_posts’ => 1_ thành WP\_Query, vì vậy get\_posts mặc định không chú ý đến các bài viết dính (sticky posts).

Dựa vào những gì được trình bày ở trên, việc sử dụng get\_posts hay WP\_Query là tùy thuộc ở bạn và việc chính xác bạn cần cái gì từ truy vấn. Những gì được trình bày ở trên sẽ giúp bạn đưa ra được lựa chọn của mình.

**Được trả lời bởi Pieter Goosen**

Tôi ước gì có thể ấn thích các câu trả lời. Câu trả lời của bạn đã giải thích cho tôi rất nhiều điều. – Patrik Alienus Jun 12 ’17 at 7:17

Giải thích quá tuyệt vời! “chỉ nên dùng get\_posts với những truy vấn không đánh trang. Việc đánh trang get\_posts thực sự sẽ gây lộn xộn. WP\_Query nên được dùng cho tất cả các truy vấn được phân trang.” Đây là những điều cơ bản mà mọi người phải biết. – Bullyen Apr 19 at 19:27

#### Câu trả lời có 29 bình chọn

Sự khác nhau cơ bản là query\_posts() thực sự chỉ nên dùng để chỉnh sửa vòng lặp hiện tại. Một khi bạn đã hoàn thành thì cần thiết lập lại vòng lặp. Phương pháp này cũng dễ hiều hơn, đơn giản là 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, giống như là:

> query\_posts(‘meta\_key=color\&meta\_value=blue’);

Mặt khác, WP\_Query là một công cụ mục đích chung (general purpose tool) và nó trực tiếp viết các truy vấn MySQL hơn so với query\_posts(). 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 đăng hiện đang chạy nào (currently running post queries).

Tôi thường sử dụng WP\_Query nhiều hơn khi điều đó xảy ra.Thực sự thì điều đó phụ thuộc vào từng trường hợp cụ thể mà bạn gặp phải.

**Được trả lời bởi nickmjones**

#### Câu trả lời có 12 bình chọn

Đơn giản là không cần thiết phải 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à giao lại đối tượng mới này cho _global wp\_query._

Để tham khảo, dưới đây là hàm query\_posts () 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 bạn nếu bạn muốn tạo tập lệnh truy vấn tùy chỉnh chuyên sâu (in depth custom query script). Hoặc sử dụng get\_posts () nếu tất cả những gì bạn cần làm là một vài thao tác đơn giản.

Trong những trường hợp khác, tôi khuyến khích cao bạn nên tự làm lấy, xem thử _wp\_includes / query.php_ và đọc qua _WP\_Query class._

**Trả lời bởi RebelPhoenix**

#### Câu trả lời có 12 bình chọn

Đả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.

**Trả lời bởi Bindiya Patoliya**

#### Câu trả lời có 8 bình chọn

Nếu tôi nhớ không nhầm về quyền đọc, về cơ bản “vòng lặp” đang thực hiện WP\_Query trong các tệp lõi, nhưng theo một cách dễ hiểu hơn.

**Trả lời bởi tw2113**

&#x20;[Vũ Thành Lâm](https://lamvt.vn/) > [Hướng dẫn học WordPress](https://lamvt.vn/category/huong-dan-hoc-wordpress/) > Khi nào nên sử dụng WP\_Query, query\_posts() và get\_posts()?

**Hot Trend:** [bảng chữ cái tiếng Việt](http://gotiengviet.com.vn/bang-29-chu-cai-tieng-viet-chuan-theo-bo-giao-duc-dao-tao/), [bảng chữ cái tiếng Nhật](http://gotiengviet.com.vn/bang-chu-cai-tieng-nhat-hiragana-katakana-kanji/), [font chữ đẹp](http://gotiengviet.com.vn/tai-8000-font-chu-dep-full-viet-hoa-cho-designer-photoshop-corel-moi-nhat/), [font vni](http://gotiengviet.com.vn/216-font-chu-vni-time-day-du-cho-windows-7-win10/), [Dạy Học mat xa](https://thammyxinh.vn/day-hoc-cham-soc-da-mat-xa/), [dạy massage body](https://thammyxinh.vn/5-buoc-co-ban-day-massage-body-tri-lieu-hieu-qua-tot-cho-suc-khoe/), [Mi Katun](https://thammyxinh.vn/5-uu-diem-cach-noi-mi-katun-khien-chi-em-do-am-am/)

#### Write a Reply or Comment <a href="#reply-title" id="reply-title"></a>

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu \*Mời bạn gửi ý kiến bình luận hoặc gióp ý
