博客 / WordPress/ WordPress代码实现post views为文章记录点击数/点击排行/有缓存及CDN使用ajax实现

WordPress代码实现post views为文章记录点击数/点击排行/有缓存及CDN使用ajax实现

WordPress代码实现post views为文章记录点击数/点击排行/有缓存及CDN使用ajax实现

WordPress 文章浏览量统计实现方案

为文章记录浏览次数并生成点击排行是许多网站的需求。本文将介绍几种实现方案,包括基础版和适用于缓存/CDN环境的增强版。

方案一:基础代码版(无缓存/CDN)

此方案适用于不使用页面缓存插件或CDN的普通动态WordPress网站。将以下代码放入主题的 functions.php 文件中即可。

代码会自动更新名为 views 的自定义字段。在需要显示浏览量的模板位置(如 single.php),调用 <?php get_post_views($post->ID); ?> 即可输出格式化后的数字。

// 文章浏览量统计与显示函数
function get_post_views($post_id) {
    $count_key = 'views';
    $count = get_post_meta($post_id, $count_key, true);
    if ($count == '') {
        delete_post_meta($post_id, $count_key);
        add_post_meta($post_id, $count_key, '0');
        $count = '0';
    }
    echo number_format_i18n($count);
}

// 设置浏览量的函数,在页面加载时触发
function set_post_views() {
    global $post;
    if ( !is_single() || !$post ) {
        return;
    }
    $post_id = $post->ID;
    $count_key = 'views';
    $count = get_post_meta($post_id, $count_key, true);

    if ($count == '') {
        $count = 0;
        delete_post_meta($post_id, $count_key);
        add_post_meta($post_id, $count_key, '0');
    } else {
        $count = intval($count) + 1;
        update_post_meta($post_id, $count_key, $count);
    }
}
// 将统计函数挂载到 get_header 动作
add_action('get_header', 'set_post_views');

注意: 如果网站使用了缓存插件(如 W3 Total Cache, WP Super Cache)或CDN服务,由于页面被静态化,服务器端的PHP代码(set_post_views)将无法在每次访问时执行,导致统计失效。此时需要使用基于AJAX的方案。

方案二:AJAX版(兼容缓存与CDN)

此方案通过前端JavaScript发起异步请求来更新浏览量,绕过页面缓存,确保每次真实访问都被记录。

步骤一:创建服务器端处理文件

在WordPress网站根目录下创建 views-ajax.php 文件(名称可自定义),并写入以下代码:

<?php
// 引入WordPress核心,以使用其函数
define('WP_USE_THEMES', false);
require('./wp-load.php');

// 安全检查:仅接受AJAX请求
if ( !isset($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest' ) {
    status_header(403);
    exit('Forbidden');
}

// 获取文章ID并验证
$post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0;
if ( $post_id <= 0 || get_post_status($post_id) === false ) {
    wp_send_json_error('Invalid post ID');
    exit;
}

// 处理浏览量更新
$current_views = get_post_meta($post_id, 'views', true);
if ( $current_views === '' ) {
    // 首次创建该字段
    $new_views = 1;
    add_post_meta($post_id, 'views', $new_views, true);
} else {
    // 更新现有值
    $new_views = intval($current_views) + 1;
    update_post_meta($post_id, 'views', $new_views);
}

// 返回新的浏览量(可选,可用于实时更新显示)
wp_send_json_success(array('views' => $new_views));
?>

步骤二:在前端页面添加统计脚本

在主题的 footer.php 文件末尾(</body>标签前),或通过 wp_footer 钩子,为文章页添加以下代码。此脚本利用 localStorage 防止同一浏览器在短时间内重复计数。

<?php if ( is_single() ) : ?>
<script>
(function() {
    // 确保页面已加载jQuery
    if (typeof jQuery === 'undefined') return;

    function recordView() {
        var postId = <?php echo get_the_ID(); ?>;
        var storageKey = 'wp_viewed_posts';
        var expireHours = 24; // 同一浏览器24小时内只计一次

        // 检查浏览器支持
        if (typeof Storage === 'undefined') {
            console.info('当前浏览器不支持本地存储,将直接发起统计。');
            sendViewRequest(postId);
            return;
        }

        // 从localStorage获取已记录的文章ID和记录时间
        var viewedData = localStorage.getItem(storageKey);
        var now = new Date().getTime();
        var shouldCount = true;

        if (viewedData) {
            try {
                viewedData = JSON.parse(viewedData);
                // 清理过期的记录
                var validData = {};
                for (var pid in viewedData) {
                    if (now - viewedData[pid] < expireHours * 3600000) {
                        validData[pid] = viewedData[pid];
                    }
                }
                viewedData = validData;

                // 检查当前文章是否在有效期内已记录
                if (viewedData.hasOwnProperty(postId)) {
                    shouldCount = false;
                }
            } catch(e) {
                // 解析失败,重置数据
                viewedData = {};
            }
        } else {
            viewedData = {};
        }

        // 如果需要计数,则发送请求并更新本地记录
        if (shouldCount) {
            sendViewRequest(postId);
            viewedData[postId] = now;
            localStorage.setItem(storageKey, JSON.stringify(viewedData));
        }
    }

    function sendViewRequest(postId) {
        jQuery.ajax({
            type: 'POST',
            url: '/views-ajax.php', // 请确保路径正确
            data: {
                post_id: postId,
                _ajax_nonce: '<?php echo wp_create_nonce("view_count_nonce"); ?>' // 增加安全性
            },
            dataType: 'json'
        }).done(function(response) {
            // 请求成功,可以在此处选择性地更新页面上的显示数字
            // console.log('View counted:', response);
        }).fail(function(jqXHR, textStatus, errorThrown) {
            console.error('View count request failed:', textStatus, errorThrown);
        });
    }

    // 页面加载完成后执行
    jQuery(document).ready(recordView);
})();
</script>
<?php endif; ?>

步骤三:显示浏览量

在文章模板中需要显示浏览量的地方,使用以下代码调用:

<?php
$views = get_post_meta(get_the_ID(), 'views', true);
echo number_format_i18n( empty($views) ? 0 : intval($views) );
?> 次阅读

方案对比与选择建议

  • 基础代码版:实现简单,但不兼容任何形式的页面缓存。仅适用于纯动态、无缓存的网站。
  • AJAX版:实现稍复杂,但能完美兼容服务器缓存、缓存插件和CDN。通过本地存储防刷,是生产环境的推荐方案。

选择时,请根据您网站的实际技术栈决定。如果使用了任何提升速度的缓存方案,请务必选择AJAX版以确保统计数据准确。

  1. avatar
    绿软吧www.lvr8.com

    感谢分享,谢谢站长!!@绿软吧

发表评论

您的邮箱不会公开。必填项已用 * 标注。