首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

WordPress 獲取指定分類及其子分類文章總數的兩種方法:單分類與遞歸統計

     編輯:PHP 相關知識

WordPress 獲取指定分類及其子分類文章總數的兩種方法:單分類與遞歸統計

在主題開發、數據統計、側邊欄展示中,常需獲取「某分類下的文章數」。本文提供四種單分類統計方法(性能遞增),及一種**遞歸統計分類及其所有子孫分類文章總數**的通用函數,並給出性能對比與選型建議。

單分類統計四種方法(性能由高到低)

方法代碼執行時間特點
1. 直接 SQL(最快)
global $wpdb;
$count = $wpdb->get_var($wpdb->prepare(
    "SELECT count FROM {$wpdb->term_taxonomy}
     JOIN {$wpdb->terms} ON {$wpdb->terms}.term_id = {$wpdb->term_taxonomy}.term_id
     WHERE {$wpdb->terms}.slug = %s", $slug));
~0.002s單次查詢,無對象開銷,適合高頻調用
2. get_category()
$cat = get_category($cat_id);
$count = $cat->count;
~0.004s返回完整分類對象,利用緩存,推薦通用
3. get_category_by_slug()
$cat = get_category_by_slug($slug);
$count = $cat->count;
~0.008s需按 slug 查詢,額外開銷
4. wp_list_categories()
echo strip_tags(wp_list_categories([
    'include' => $cat_id,
    'show_count' => 1,
    'echo' => 0,
    'style' => 'none',
]));
~0.015s輸出 HTML 後再 strip_tags,最慢,僅供顯示用

注意:以上方法**均不包含子分類文章數**,僅統計該分類直接掛載的文章。

遞歸統計:分類 + 所有子孫分類文章總數

<?php
/**
 * 獲取分類及其所有子孫分類的文章總數
 * @param int $cat_id 分類 ID
 * @return int 總文章數
 */
function ludou_get_cat_tree_post_count($cat_id) {
    $cat = get_category($cat_id);
    if (!$cat) return 0;

    $count = (int) $cat->count; // 當前分類文章數

    // 獲取所有子孫分類(child_of 參數遞歸查詢)
    $children = get_terms([
        'taxonomy'   => 'category',
        'child_of'   => $cat_id,
        'hide_empty' => false, // 包含空分類
        'fields'     => 'ids', // 僅返回 ID,提升性能
    ]);

    if ($children) {
        // 批量獲取子分類對象並累加 count
        $child_cats = get_categories([
            'include' => $children,
            'hide_empty' => false,
        ]);
        foreach ($child_cats as $child) {
            $count += $child->count;
        }
    }

    return $count;
}

使用示例

// 單分類
echo '分類 "news" 文章數:' . ludou_get_cat_tree_post_count(get_category_by_slug('news')->term_id);

// 模板中顯示
$cat_id = 123;
printf(
    '分類 %s 及其子分類共有 %d 篇文章',
    get_cat_name($cat_id),
    ludou_get_cat_tree_post_count($cat_id)
);

性能優化版(單次查詢,適合超大分類樹)

function ludou_get_cat_tree_post_count_fast($cat_id) {
    global $wpdb;
    // 利用 term_taxonomy 表的 parent 字段遞歸查詢所有子孫 term_id
    $sql = "SELECT SUM(count) FROM {$wpdb->term_taxonomy}
            WHERE term_id IN (
                SELECT term_id FROM (
                    SELECT term_id FROM {$wpdb->term_taxonomy}
                    WHERE taxonomy = 'category'
                    START WITH term_id = %d
                    CONNECT BY PRIOR term_id = parent
                ) t
            )";
    // MySQL 8.0+ 支援 WITH RECURSIVE,MariaDB 10.2+ 支援 CONNECT BY
    // 低版本需用存儲過程或 PHP 端遞歸
    return (int) $wpdb->get_var($wpdb->prepare($sql, $cat_id));
}

MySQL 8.0+ 標準遞歸 CTE 寫法:

WITH RECURSIVE cat_tree AS (
    SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_id = %d AND taxonomy = 'category'
    UNION ALL
    SELECT tt.term_id FROM {$wpdb->term_taxonomy} tt
    JOIN cat_tree ct ON tt.parent = ct.term_id
    WHERE tt.taxonomy = 'category'
)
SELECT SUM(count) FROM {$wpdb->term_taxonomy}
WHERE term_id IN (SELECT term_id FROM cat_tree);

選型建議

  • 單分類、高頻調用:直接 SQL 或 `get_category()`(利用緩存)。
  • 需要子分類統計、分類樹深度 < 5 層:PHP 端 `get_terms(child_of)` + 批量 `get_categories()`,清晰易維護。
  • 分類樹極深、文章數百萬級:資料庫端遞歸 CTE(MySQL 8.0+/MariaDB 10.2+)單次查詢最快。
  • 前端顯示「分類名 (數量)」:`wp_list_categories()` 一站式輸出,接受性能代價。

緩存策略

// 緩存 1 小時,發布/刪除文章時清理
function ludou_get_cat_count_cached($cat_id, $with_children = false) {
    $key = 'cat_count_' . $cat_id . ($with_children ? '_tree' : '');
    $count = wp_cache_get($key, 'ludou_counts');
    if ($count !== false) return $count;

    $count = $with_children
        ? ludou_get_cat_tree_post_count($cat_id)
        : get_category($cat_id)->count;

    wp_cache_set($key, $count, 'ludou_counts', HOUR_IN_SECONDS);
    return $count;
}

// 掛載清理鉤子
add_action('transition_post_status', function($new, $old, $post) {
    if ($post->post_type === 'post') {
        wp_cache_flush('ludou_counts');
    }
});

掌握單分類與樹狀統計的區別,選對方法並加上緩存,能讓分類文章數顯示既準確又高效。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved