WordPress 粗略统计全站文章字数

LMS
1K+ 13

已经搞定,原来确实是代码有问题,多此一举的用了取 ID 然后用 get_the_content 出了问题,不知道为什么这货直接运行函数可以,使用钩子时失效,可用代码见最后。

没事瞎折腾,想搞个统计 WordPress 博客全站文字字数的功能,当然只是粗略统计,却遇到个奇怪的问题,直接用函数可以,用 add_action 钩子就不行,各位走过路过的大佬帮忙看看。

代码如下:

function lmsim_allPost_words(){
  $args = array(
    'post_type' => array('post','page'),
    'post_status' => 'publish',
    'posts_per_page' => -1,
    'ignore_sticky_posts' => 1
  );
  $post_data = get_posts($args); //整出公布的所有文章和页面
          
  if($post_data){
    $total_words = 0;
    $post_ids = array_column($post_data, 'ID'); //取出所有文章页面的 ID

    foreach ($post_ids as $post_id) {
      $content = get_the_content($post_id); //取ID对于的文章内容
      $content = preg_replace("/[^\x{4e00}-\x{9fa5}]/u", "", $content); //去掉一些html内容
      $total_words += mb_strlen(trim($content),'UTF-8'); //文字去空计数格累加
    }
    update_option( 'total_words', $total_words); //存储到数据库中
  }
}
add_action( 'publish_post', 'lmsim_allPost_words'); //发布文章钩子
add_action( 'edit_post', 'lmsim_allPost_words'); //编辑文章钩子

就上面这个代码,我直接 echo 后,调用 lmsim_allPost_words(),它可以显示,就是要稍微转一两圈圈,可能文章太多。但是用钩子在发布和编辑文章时运行然后存储到数据库了,再用 get_option('total_words',true) 直接取就不行。而且即使原来数据库里有数字,钩子一动,数值就是 0。本来以为是文章太多钩子忙不过来脱钩,可测试新站一两篇也是一样变 0,就很奇怪。

为啥直接函数输出可以,用钩子就不行呢?百撕不得其姐!各位大佬教我。

可用代码如下,不过上面那个过滤html内容的那行好像用的不对,会薅掉很大部分的内容,所以重新找了个过滤办法。

function lmsim_allPost_words(){
  $args = array(
    'post_type' => array('post','page'),
    'post_status' => 'publish',
    'posts_per_page' => -1,
    'ignore_sticky_posts' => 1
  );
  $post_data = get_posts($args); //整出公布的所有文章和页面
          
  if($post_data){
    $total_words = 0;

    foreach ($post_data as $post) {
      $content = $post->post_content; //遍历所有文章内容
      $content = preg_replace('/<[^>]*>/', '', $content); //过滤html标签
      $content = preg_replace('/<img[^>]*>/i', '', $content); //过滤图片标签
      $content = preg_replace('/\s+/', '', $content); //过滤空格
      $total_words += mb_strlen($content,'UTF-8'); //文字计数累加
    }
    update_option( 'total_words', $total_words); //存储到数据库中
  }
}
add_action( 'publish_post', 'lmsim_allPost_words'); //发布文章钩子
add_action( 'edit_post', 'lmsim_allPost_words'); //编辑文章钩子
THE END

评论 13

  1. https://github.com/ann61c/wp-post-heatmap/blob/main/functions.php
    ```
    function wp_post_heatmap_get_post_data()
    {
    $args = array('numberposts' => -1, // Fetch all posts
    );
    $posts = get_posts($args);
    $post_data = array();

    foreach ($posts as $post) {
    $date = get_the_date('Y-m-d', $post);
    $word_count = mb_strlen(strip_tags(strip_shortcodes($post->post_content)), 'UTF8');
    $title = get_the_title($post);
    $url = get_permalink($post->ID);
    $post_data[] = array('date' => $date, 'word_count' => $word_count, 'title' => $title, 'url' => $url);
    }

    return $post_data;
    }
    ```

    参考这段?

  2. get_the_XXX这组函数都是要在【while ( have_posts() ) : the_post()】的循环里用的。第一种写法可能要用get_post_field。

    1. 确实是这个问题,get_post_field用的非常少,基本想不到。

  3. 功能越多,速度会不会越慢呀。

    1. 多个功能就需要多一份算力,肯定会有影响。

  4. bigfa
    🏆🏅

    get_the_content 第三个参数才是文章id,直接调用你能显示出数字估计是在文章页面上,全局变量$post 已经有值了。

    1. 我也想着估计是需要在wp主循环里用的原因,因为用的位置都一样,在页面底部,不在循环内,所以就一直觉得很奇怪。

      1. bigfa@LMS
        🏆🏅

        不需要在循环内,只要$post 被赋值了就能出统计 :shock: 你在functions.php里直接调用估计就没了

        1. 那我修改后的代码foreach的时候用$post这个wp原来就有的变量,是不是不好,容易出问题。 :arrow:

    1. 原来你已经有轮子了,不过我们思路差不多,你是直接拉数据库的字段,我是用wp自带函数循环字段,后面根据字数类比哪本书的我可以直接抄作业了。你那个字数统计水分就是没过滤图片空格等html标签,像markdown语法什么的也都统计了,没法考虑那么多,已经很好了。

  5. 关注,我也想知道,哈哈

发表评论

Submit