在 WordPress 開發中,get_post() 與 get_posts() 雖名稱相似,但用途、參數、回傳結構截然不同。前者獲取單篇文章物件/陣列,後者獲取多篇文章陣列並支援豐富查詢參數。本文將詳細對比兩者,並提供實戰範例與效能建議。
get_post( int|WP_Post|null $post = null, string $output = OBJECT, string $filter = 'raw' ): WP_Post|array|null
| 參數 | 說明 |
|---|---|
$post | 文章 ID(整數)或 WP_Post 物件。注意:不能直接傳入字面量整數(如 get_post(123) 會報錯),必須先指派給變數。 |
$output | 回傳格式:OBJECT(預設,WP_Post 物件)、ARRAY_A(關聯陣列)、ARRAY_N(數值陣列) |
$filter | 資料過濾模式:raw(預設)、edit、db、display |
// 正確:先指派變數 $post_id = 158; $post_obj = get_post( $post_id ); // 回傳 WP_Post 物件 $title = $post_obj->post_title; // 獲取關聯陣列 $post_arr = get_post( $post_id, ARRAY_A ); $content = $post_arr['post_content']; // 獲取數值陣列(較少用) $post_num = get_post( $post_id, ARRAY_N ); // $post_num[0] = ID, $post_num[1] = post_author, ... 依資料表欄位順序
setup_postdata() 暫時切換全域 $post 變數get_posts( array|string $args = array() ): WP_Post[]
參數結構與 WP_Query 高度相容,以下為常用參數:
| 參數 | 類型 | 預設值 | 說明 |
|---|---|---|---|
numberposts | int | 5 | 獲取文章數量,-1 表無限制 |
offset | int | 0 | 跳過前幾篇 |
category | int|string|array | 分類 ID,支援多個、負數排除 | |
category_name | string | 分類別名 | |
tag | string | 標籤別名 | |
orderby | string | 'post_date' | 排序依據(見下表) |
order | string | 'DESC' | 'ASC' 或 'DESC' |
include | array | 指定文章 ID 陣列 | |
exclude | array | 排除文章 ID 陣列 | |
meta_key | string | 自訂欄位鍵名 | |
meta_value | string | 自訂欄位值 | |
meta_query | array | 複雜自訂欄位查詢(WP 4.4+) | |
post_type | string|array | 'post' | 文章類型:'post', 'page', 'attachment', 'any', 或 CPT slug |
post_status | string|array | 'publish' | 文章狀態:'publish', 'draft', 'pending', 'private', 'trash', 'any' |
suppress_filters | bool | true | 是否抑制 posts_results 等過濾器 |
'author' // 作者 ID 'category' // 分類 ID 'comment_count'// 留言數 'date' // 發布日期 'ID' // 文章 ID 'menu_order' // 選單順序(頁面適用) 'modified' // 最後修改時間 'name' // 文章別名 'parent' // 父文章 ID 'rand' // 隨機排序 'title' // 標題 'type' // 文章類型
$latest_posts = get_posts( [
'numberposts' => 5,
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC',
] );
// 字串參數簡寫
$random_posts = get_posts( 'numberposts=3&orderby=rand' );
// 陣列參數完整寫法
$random_posts = get_posts( [
'numberposts' => 3,
'orderby' => 'rand',
'post_status' => 'publish',
] );
$cat_posts = get_posts( [
'numberposts' => 10,
'category' => 5, // 分類 ID
// 或 'category_name' => 'news'
] );
$featured_posts = get_posts( [
'meta_key' => 'is_featured',
'meta_value' => 'yes',
'post_type' => 'post',
] );
$images = get_posts( [
'post_type' => 'attachment',
'post_mime_type' => 'image',
'post_parent' => $post_id, // 該文章的附件
'numberposts' => -1,
'orderby' => 'menu_order',
'order' => 'ASC',
] );
| 特性 | get_post() | get_posts() |
|---|---|---|
| 用途 | 單篇文章詳情 | 多篇文章列表 |
| 第一參數 | 文章 ID/物件(必填) | 查詢參數陣列(選填) |
| 回傳類型 | WP_Post / array / null | WP_Post[] (陣列) |
| 支援查詢參數 | 無 | 豐富(類 WP_Query) |
| 資料庫查詢 | 單行查詢(極快) | SELECT 列表查詢 |
| 快取機制 | 內建物件快取 | 內建物件快取 |
| 影響主循環 | 否 | 否 |
$my_posts = get_posts( ['numberposts' => 3] );
if ( $my_posts ) {
global $post;
foreach ( $my_posts as $post ) {
setup_postdata( $post );
// 現在可以使用 the_title(), the_permalink(), the_excerpt() 等模板標籤
echo '<h3><a href="' . get_permalink() . '">' . get_the_title() . '</a></h3>';
the_excerpt();
}
wp_reset_postdata(); // 重要:恢復全域 $post
}
// ❌ 慢:迴圈中重複查詢自訂欄位
foreach ( $posts as $post ) {
$meta = get_post_meta( $post->ID, 'key', true );
}
// ✅ 快:使用 meta_query 一次撈取
$posts = get_posts( [
'meta_key' => 'key',
// 或 meta_query 更複雜條件
] );
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$posts = get_posts( [
'numberposts' => 10,
'offset' => ( $paged - 1 ) * 10,
] );
當需要更複雜查詢(多重分類、關係查詢、日期範圍、分頁物件)時,建議直接使用 WP_Query:
$query = new WP_Query( [
'post_type' => 'product',
'tax_query' => [
'relation' => 'AND',
['taxonomy' => 'category', 'field' => 'slug', 'terms' => 'sale'],
['taxonomy' => 'pa_color', 'field' => 'slug', 'terms' => ['red', 'blue']],
],
'meta_query' => [
['key' => 'price', 'value' => [100, 500], 'type' => 'NUMERIC', 'compare' => 'BETWEEN'],
],
'posts_per_page' => 12,
'paged' => $paged,
] );
get_post(123)$id = 123; get_post($id);post_status 是否正確(預設只抓 'publish'),或 suppress_filters 是否被外掛影響。ORDER BY RAND() 在大資料量極慢。替代方案:預先產生隨機 ID 陣列、使用 offset 隨機跳過、或外掛 WP_Random_Posts。category (ID) 或 category_name (slug),不要混用。多個分類用陣列 [1, 2, 3]。get_post():wp-includes/post.php(約第 900 行)get_posts():wp-includes/post.php(約第 2100 行),內部實際呼叫 WP_Query