描述
query_posts() 可以用來(lái)控制在循環(huán)(Loop)中顯示哪些文章。它可以替換主查詢,而使用一個(gè)新的查詢來(lái)獲取文章。要清除 query_posts() 的新查詢,可以使用 wp_reset_query() 來(lái)重置查詢。
我們強(qiáng)烈建議您使用 pre_get_posts 來(lái)替代 query_posts() ,同時(shí)使用 is_main_query 來(lái)檢查主查詢。
舉個(gè)例子,在首頁(yè)(homepage),你可以看到最新的10篇文章。如果你想僅僅顯示 5 篇文章(不在乎分頁(yè)),你可以像這樣使用 query_posts() :
query_posts( 'posts_per_page=5' );
下面是在 functions.php 中使用 pre_get_posts 實(shí)現(xiàn)類型的結(jié)果:
function five_posts_on_homepage( $query ) {
if ( $query->is_home() && $query->is_main_query() ) {
$query->set( 'posts_per_page', '5' );
}
}
add_action( 'pre_get_posts', 'five_posts_on_homepage' );
注:pre_get_posts 動(dòng)作無(wú)法正常工作于 頁(yè)面(Page) 查詢。
注意事項(xiàng)
query_posts() 只是一種查詢數(shù)據(jù)庫(kù)獲取文章列表的方法。在使用 query_posts() 之前,你需要了解它的弊端。
改變主循環(huán)(Alters Main Loop)
query_posts() 是通過(guò)替換查詢條件來(lái)改變主循環(huán)生成的內(nèi)容的。一旦你使用 query_posts(), 你文章的相關(guān)的全局變量和模板標(biāo)簽都將改變。條件標(biāo)簽(Conditional tags)在你調(diào)用 query_posts() 之后也會(huì)發(fā)生改變——這可能是也可能不是預(yù)期的結(jié)果。
二級(jí)循環(huán)(Secondary Loops)
要?jiǎng)?chuàng)建 二級(jí)列表(例如:在頁(yè)面底部顯示相關(guān)文章列表,或者在邊欄小工具中顯示一個(gè)列表), 嘗試使用 WP_Query 或 get_posts() 來(lái)獲取文章。
如果你一定要用 query_posts() ,請(qǐng)確保你在上一個(gè)使用了 query_posts() 的循環(huán)結(jié)束的地方,使用 wp_reset_query() 來(lái)重置查詢。
分頁(yè)(Pagination)
分頁(yè)將無(wú)法正常工作,除非你適當(dāng)設(shè)置 ‘paged’ 查詢: adding the paged parameter
額外的SQL查詢
如果你在模板頁(yè)面中使用 query_posts ,WordPress 就會(huì)在 query_posts 時(shí)執(zhí)行數(shù)據(jù)庫(kù)查詢和檢索記錄(即它是如何知道是服務(wù)于哪個(gè)模板頁(yè)面!)所以,當(dāng)你使用 query_posts() 覆蓋了默認(rèn)的查詢,你基本上就扔掉了默認(rèn)的查詢以及它的結(jié)果,并重新對(duì)數(shù)據(jù)庫(kù)執(zhí)行了另一個(gè)查詢。
這也許不是一個(gè)問(wèn)題,尤其是如果你正在處理一個(gè)較小的基于博客的網(wǎng)站。但是對(duì)于大型網(wǎng)站、大型數(shù)據(jù)庫(kù)以及較高的訪客流量來(lái)說(shuō),你就要考慮使用其他查詢方式來(lái)減少 SQL查詢了,比如直接修改默認(rèn)的查詢(在它被請(qǐng)求前)。使用請(qǐng)求(request)過(guò)濾器可是實(shí)現(xiàn)這點(diǎn)。
‘parse_query’ 和 ‘pre_get_posts’ 過(guò)濾器也可用來(lái)修改內(nèi)部用于生成SQL查詢數(shù)據(jù)庫(kù)的 $query 對(duì)象。
用法
<?php
// 查詢
query_posts( $args );
// 循環(huán)
while ( have_posts() ) : the_post();
echo '<li>';
the_title();
echo '</li>';
endwhile;
// 重置查詢
wp_reset_query();
?>
在模板文件的循環(huán)前面添加 query_posts() ,wp_query 對(duì)象將根據(jù)你給定的參數(shù)生成一個(gè)新的 SQL 查詢。當(dāng)你這樣做時(shí),WordPress 將忽視通過(guò)URL檢索到的其他參數(shù)(例如 頁(yè)碼或分類)。
保留現(xiàn)有的查詢參數(shù)
如果你想保留原來(lái)的查詢參數(shù)作為當(dāng)前查詢的一部分,然后添加或重寫一些參數(shù),你可以在 query_posts() 中使用全局變量 $query_string 。
例如,要修改文章的顯示順序并且不影響接下來(lái)的查詢,你可以在循環(huán)(The Loop)前面使用下面的代碼:
global $query_string;
query_posts( $query_string . '&order=ASC' );
當(dāng)你通過(guò)這種方式使用 query_posts() , 參數(shù)的前面必須添加一個(gè) & 。或者你可以合并原來(lái)的查詢數(shù)組到到你的參數(shù)數(shù)組:
global $wp_query;
$args = array_merge( $wp_query->query_vars, array( 'post_type' => 'product' ) );
query_posts( $args );
結(jié)合參數(shù)
從上面的例子中,你可能已經(jīng)注意到,你可以使用 & 來(lái)結(jié)合參數(shù):
query_posts( 'cat=3&year=2004' );
在首頁(yè)查詢當(dāng)前月份的分類ID為 13 的文章:
if ( is_home() ) {
query_posts( $query_string . '&cat=13&monthnum=' . date( 'n', current_time( 'timestamp' ) ) );
}
下面的例子,將返回一組文章(分類ID為 1 和 3 、顯示 2 篇文章、根據(jù)標(biāo)題降序排列):
query_posts( array( 'category__and' => array(1,3), 'posts_per_page' => 2, 'orderby' => 'title', 'order' => 'DESC' ) );
下面的例子將返回分類ID為 1 和 標(biāo)簽為 “apples”的文章:
query_posts( 'cat=1&tag=apples' );
你可以使用加號(hào) + 來(lái)添加更多標(biāo)簽:
query_posts( 'cat=1&tag=apples+apples' );
參數(shù)
參數(shù)詳情請(qǐng)閱讀 Parameter section of the WP_Query class article.
下面的例子同樣可以用于 WP_Query 對(duì)象。
例子
在首頁(yè)排除分類
將下面的代碼添加到 index.php 文件,這樣首頁(yè)將顯示 除了分類ID為 3 以外的其他所有文章:
<?php
if ( is_home() ) {
query_posts( 'cat=-3' );
}
?>
你還可以以此類推添加更多要排除的分類:
<?php
if ( is_home() ) {
query_posts( 'cat=-1,-2,-3' );
}
?>
檢索某一篇文章
要檢索某一篇文章,可以使用下面的代碼:
query_posts( 'p=5' );
注:如果檢索的是一個(gè)附件,那你應(yīng)該使用 attachment_id 代替 p :
query_posts( 'attachment_id=5' );
如果你想使用“閱讀更多(Read More)”功能,你就需要在查詢中設(shè)置全局變量 $more 的值為 0 :
<?php
// 檢索 ID 為 5 的文章
query_posts( 'p=5' );
// 設(shè)置 $more 為 0 以便僅僅獲取文章的第一部分
global $more;
$more = 0;
// 循環(huán)
while (have_posts()) : the_post();
the_content( '閱讀全文 ?' );
endwhile;
?>
一個(gè)分類的所有文章
在 設(shè)置 > 閱讀 中,“博客頁(yè)面最多顯示”的設(shè)置可以影響你的結(jié)果。為了克服這個(gè)問(wèn)題,你可以添加 ‘posts_per_page’ 參數(shù),例如:
query_posts( array ( 'category_name' => 'my-category-slug', 'posts_per_page' => -1 ) );
這樣將顯示這個(gè)分類的所有文章。
但是,對(duì)于子分類(subcategories or child categories), ‘The Category Name’ 可能就沒(méi)辦法生效,請(qǐng)使用 ‘category-slug’ 替代。閱讀 Function_Reference/is_category。
if (is_category('category-slug')):
query_posts(array('category_name' => 'my-category-slug', 'posts_per_page' => -1 ));
endif;
聚合 Feeds
在 設(shè)置 > 閱讀 中,“Feed 中顯示最近”的設(shè)置 或者 ‘posts_per_rss’ 參數(shù)將在 Feed 中覆蓋任何查詢的 ‘posts_per_page’ 參數(shù)。
為了克服這個(gè)問(wèn)題(例如在自定義的 ics Feed 中,輸出所有符合條件的文章),可以使用 "posts_limit" 過(guò)濾器:
if ( isset ( $query->query_vars['feed'] ) and ( $query->query_vars['feed'] == 'ics' ) )
{
add_filter( 'post_limits', '__return_empty' );
}
傳遞變量到 query_posts
有兩種方法可以傳遞一個(gè)變量到查詢中,你可以根據(jù)自己的需求選擇。就像其他例子一樣,將下面的代碼添加到循環(huán)的上面:
例 1
在這個(gè)例子中,我們?cè)诓樵冞\(yùn)行前串連查詢條件。首先分配變量,然后串連,然后運(yùn)行它。在這里,我們從其他地方拉來(lái)一個(gè)分類變量:
// 分配參數(shù)作為當(dāng)前分類
$categoryvariable = $cat;
// 串連查詢
$args = 'cat=' . $categoryvariable . '&orderby=date&order=ASC';
// 運(yùn)行查詢
query_posts( $args );
例 2
在這個(gè)例子中,雙引號(hào)是告訴 PHP 這是一個(gè)閉合。對(duì)于這個(gè)例子,我們獲取當(dāng)前 月份 和 年份,然后告訴 query_posts() 顯示當(dāng)前 年/月 的文章。此外,我們使用升序排列(ASE) ,這樣,最老的文章將顯示在頁(yè)面的頂部:
$current_year = date('Y');
$current_month = date('m');
query_posts( "cat=22&year=$current_year&monthnum=$current_month&order=ASC" );
例 3
這個(gè)例子解析如何刪除一個(gè)完整的文章列表,并且進(jìn)行分頁(yè)處理。我們可以使用默認(rèn)的 $query_string 告訴 query_posts() 顯示所有文章列表。我們還可以自定義 posts_per_page 這個(gè)查詢參數(shù)為 –1 到 任何數(shù)量 來(lái)設(shè)置每頁(yè)顯示的文章數(shù)。最后,你可能想使用 posts_nav_link() 來(lái)導(dǎo)航生成的文章存檔。
query_posts( $query_string . '&posts_per_page=-1' );
例 4
如果你不需要使用 $query_string 變量,另一種方法是將所有的參數(shù)添加到一個(gè)數(shù)組中,即使在更加復(fù)雜的情況下,也清晰明了。上面 例 2 可以使用下面的代碼實(shí)現(xiàn):
$args = array(
'cat' => 22,
'year' => $current_year,
'monthnum' => $current_month,
'order' => 'ASC'
);
query_posts( $args );
正如你所見(jiàn),通過(guò)這種方式,所有的變量都放置在獨(dú)立的行中,這就非常容易閱讀了。
例 5
它甚至可以使用數(shù)組方式(例 4)來(lái)查詢多個(gè)分類。只需提供分類別名(taxonomy slug),多個(gè)別名使用逗號(hào)隔開(kāi)。在下面的例子中,我們會(huì)得到 Bruce Campbell 或 Chuck Norris 的movie文章:
$args = array(
'post_type'=> 'movie',
'actor' => 'Bruce Campbell, Chuck Norris',
'order' => 'ASC'
);
query_posts( $args );
所在文件
query_posts() 包含在 wp-includes/query.php.
其他資源
為了更深入的討論 WordPress 生成和處理查詢,請(qǐng)閱讀這些文章:
- Query Overview 和 Custom Queries
- 正確使用’pre_get_posts的自定義默認(rèn)查詢 – Bill Erickson – Customize the WordPress Query 或 John James Jacoby – Querying Posts Without query_posts
- 你不知道的查詢 – Slides from WordCamp Netherlands 2012 by Andrew Nacin
- WordPress函數(shù) 之 query_posts用法匯總
相關(guān)函數(shù)
類: WP_Query – 詳細(xì)的 WP_Query 類概述
類: $wpdb – 使用 $wpdb 對(duì)象的概述
函數(shù): get_query_var()
函數(shù): get_posts() – 一個(gè)專門返回文章數(shù)組的函數(shù)
函數(shù): get_pages() – 一個(gè)專門返回頁(yè)面數(shù)組的函數(shù)
函數(shù): have posts() – 一個(gè)確定查詢是否返回文章的條件
函數(shù): the_post() – 用于自動(dòng)設(shè)置查詢后的循環(huán)
函數(shù): rewind_posts() – 重置當(dāng)前循環(huán)
函數(shù): setup_postdata() – 為循環(huán)中的私有查詢?cè)O(shè)置查詢數(shù)據(jù)
函數(shù): wp_reset_postdata() – 恢復(fù)以前的查詢(通常在一環(huán)內(nèi)循環(huán))
函數(shù): wp_reset_query()
函數(shù): is_main_query() – 確保被改變的僅僅是主查詢
動(dòng)作鉤子: pre_get_posts – 在執(zhí)行之前修改 WordPress 的查詢
過(guò)濾鉤子: found_posts – 修改 WP_Query 對(duì)象的 found_posts 的值
教程: Displaying Posts Using a Custom Select Query
教程: Making Advanced Taxonomy Queries
教程: Making Custom Queries using Offset and Pagination
- 原文:http://codex.wordpress.org/Function_Reference/query_posts
- 翻譯:倡萌@WordPress大學(xué) – WordPress函數(shù):query_posts(查詢文章)





為什么我在rss里面能看到文章,但是用軟件就獲取不到呢,我還加了防采集的代碼。
wp_reset_query()和 wp_reset_query() 一般都是配對(duì)使用的吧