You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单页面多视频独立播放量统计AJAX存库故障排查求助

单页多视频播放量统计AJAX存储失败问题排查

问题描述

找不到能在单页多视频场景下统计单个视频播放量的插件,现有计数插件基本都是针对页面或文章的,所以自行开发,但遇到问题:
通过jQuery实现了点击播放图标时计数前端显示增加,但AJAX将增量后的播放量保存到数据库时失败。

子主题模板代码

<?php
/**
 * Template Name: All Videos Template
 */
get_header();
?>
<script>
jQuery(document).ready(function($) {
    // Attach click event listener to play icons
    $('.video-item .play-icon').on('click', function(e) {
        e.preventDefault();

        var videoContainer = $(this).closest('.video-item');
        var videoId = videoContainer.data('video-id');
        var viewCountElement = videoContainer.find('.view-count');

        // Send AJAX request to update view count
        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'update_view_count',
                post_id: videoId
            },
            success: function(response) {
                // Update view count in the container
                viewCountElement.text(response);
            },
            error: function() {
                console.log('Error occurred during AJAX request.');
            }
        });
    });
});
</script>
<div id="primary" class="content-area">
    <main id="main" class="site-main">

        <?php
        // Query to retrieve all attachments
        $args = array(
            'post_type'      => 'attachment',
            'post_mime_type' => 'video',
            'post_status'    => 'inherit',
            'posts_per_page' => -1,
          /*  'orderby'        => 'rand', // Randomize video listing*/
        );

        $video_query = new WP_Query($args);

        if ($video_query->have_posts()) :
            ?>
            <div class="video-grid">
                <?php
                while ($video_query->have_posts()) :
                    $video_query->the_post();
                    $video_url    = wp_get_attachment_url(get_the_ID());
                    $attachment_page_url = get_permalink();
                    $attachment_page_title = get_the_title(get_post()->post_parent);
                    
                    // Check if the attachment URL starts with the 'escort' slug
                    if (strpos($attachment_page_url, '/escort/') !== false) :
                        // Get the video views count
                        $video_id = get_the_ID();
                        $video_views = (int) get_post_meta($video_id, 'wpzu_video_views', true); // Modified meta key
                        ?>
                        <div class="video-item">
                            <a href="<?php echo esc_url($attachment_page_url); ?>" target="_blank" rel="noopener noreferrer">
                                <video id="video-<?php echo esc_attr($video_id); ?>" src="<?php echo esc_url($video_url); ?>" controls loading="lazy"></video>
                            </a>
                            <div class="video-details">
                                <h2>
                                    <a href="<?php echo esc_url($attachment_page_url); ?>" target="_blank" rel="noopener noreferrer">
                                        <?php echo esc_html($attachment_page_title); ?>
                                    </a>
                                </h2>
                                <p class="view-count" data-video-id="<?php echo esc_attr($video_id); ?>">
                                    <?php echo esc_html($video_views); ?>&nbsp;Views
                                </p>
                            </div>
                        </div>
                        <script>
                        document.getElementById('video-<?php echo esc_js($video_id); ?>').addEventListener('play', function() {
                            // Increment the video views count
                            var viewCountElement = document.querySelector('.view-count[data-video-id="<?php echo esc_attr($video_id); ?>"]');
                            var currentViewCount = parseInt(viewCountElement.innerText.replace('Views: ', ''));
                            var newViewCount = currentViewCount + 1;
                            viewCountElement.innerText = 'Views: ' + newViewCount;
                            // Send AJAX request to update the view count in the database
                            jQuery.ajax({
                                url: ajaxurl,
                                type: 'POST',
                                data: {
                                    action: 'update_view_count',
                                    video_id: <?php echo esc_js($video_id); ?>,
                                    view_count: newViewCount
                                },
                                success: function(response) {
                                    console.log('View count updated successfully.');
                                },
                                error: function() {
                                    console.log('Error occurred during AJAX request.');
                                }
                            });
                        });
                        </script>
                        <?php
                    endif;
                endwhile;
                wp_reset_postdata();
                ?>
            </div>
        <?php
        else :
            echo 'No videos found.';
        endif;
        ?>

    </main><!-- #main -->
</div><!-- #primary -->

<?php
get_footer();
?>

子主题functions.php中的AJAX代码

// Enqueue the JavaScript file for AJAX
function enqueue_custom_scripts() {
    wp_enqueue_script( 'custom-ajax-script', get_stylesheet_directory_uri() . '/js/custom-ajax.js', array( 'jquery' ), '1.0', true );
    wp_localize_script( 'custom-ajax-script', 'customAjax', array( 'ajaxUrl' => admin_url( 'admin-ajax.php' ) ) );
}
add_action( 'wp_enqueue_scripts', 'enqueue_custom_scripts' );

// Update view count via AJAX
function update_view_count_ajax() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'postmeta'; // Replace 'wpzu_' with your desired prefix

    if (isset($_POST['post_id'])) {
        $post_id = intval($_POST['post_id']);
        $video_views = (int) $wpdb->get_var( $wpdb->prepare(
            "SELECT meta_value FROM $table_name WHERE meta_key = 'video_views' AND post_id = %d",
            $post_id
        ) );
        
        $video_views++;
        
        $wpdb->update(
            $table_name,
            array( 'meta_value' => $video_views ),
            array( 'meta_key' => 'video_views', 'post_id' => $post_id ),
            array( '%d' ),
            array( '%s', '%d' )
        );
        
        echo $video_views;
    }
    
    wp_die(); // Always include this line to terminate the AJAX call properly
}
add_action( 'wp_ajax_update_view_count', 'update_view_count_ajax' );
add_action( 'wp_ajax_nopriv_update_view_count', 'update_view_count_ajax' );

问题排查与修复方案

1. AJAX URL不匹配

模板内联脚本使用ajaxurl全局变量,但functions.php里本地化的是customAjax.ajaxUrl,且内联脚本未依赖注册的custom-ajax-script,导致ajaxurl可能未定义(前端控制台会报错)。
修复:将内联脚本中的url: ajaxurl替换为url: customAjax.ajaxUrl。

2. 元键名称不一致

模板中获取播放量用的是wpzu_video_views,但PHP代码中查询和更新的是video_views,两者不匹配导致无法正确读写数据。
修复:统一元键名称为wpzu_video_views。

3. 前端文本替换逻辑错误

播放量显示文本是X Views,但play事件里用replace('Views: ', ''),替换后仍为X Views,parseInt会返回NaN,导致计数错误。
修复:改为parseInt(viewCountElement.innerText.replace(' Views', '')),同时更新前端显示文本为newViewCount + ' Views'保持一致。

4. AJAX传参不匹配

play事件中AJAX传的参数是video_id,但PHP代码只判断$_POST['post_id'],导致请求无法被处理。
修复:在PHP代码中同时兼容两种参数:

$post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : intval($_POST['video_id']);

5. 直接操作数据库表不规范

使用$wpdb直接操作postmeta表不如用WordPress内置的get_post_meta和update_post_meta函数,更安全简洁,还能自动处理元数据的创建(如果不存在)。
修复后的PHP函数示例:

// Update view count via AJAX
function update_view_count_ajax() {
    $post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : (isset($_POST['video_id']) ? intval($_POST['video_id']) : 0);
    
    if (!$post_id) {
        wp_die();
    }

    $video_views = (int) get_post_meta($post_id, 'wpzu_video_views', true);
    $video_views++;
    
    update_post_meta($post_id, 'wpzu_video_views', $video_views);
    
    echo $video_views;
    wp_die();
}

6. 重复事件绑定

模板中同时绑定了.play-icon的点击事件和video的play事件,可能导致同一播放行为触发两次AJAX请求,造成计数重复增加。
修复:保留其中一种事件绑定即可,推荐用video的play事件(更准确,用户可能直接点击视频播放按钮而非外部图标)。

内容的提问来源于stack exchange,提问作者Godman Umoeka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 04:47:48