文章目录[隐藏]
详细教程:集成网站访问统计与流量分析工具,通过WordPress程序的代码二次开发实现常用互联网小工具功能
引言:为什么需要自定义统计与工具集成?
在当今数字化时代,网站不仅仅是信息展示的平台,更是与用户互动、收集数据、优化体验的重要工具。对于WordPress网站管理员而言,了解访客行为、分析流量来源、优化内容策略是持续成功的关键。虽然市面上有Google Analytics、百度统计等成熟解决方案,但通过WordPress代码二次开发实现自定义统计和小工具集成,能够带来以下独特优势:
- 数据自主性:完全掌控数据收集、存储和处理流程
- 深度定制:根据特定业务需求设计统计维度
- 性能优化:减少对外部服务的依赖,提升页面加载速度
- 隐私合规:更好地适应GDPR等数据保护法规
- 成本控制:长期来看可能降低第三方服务费用
本教程将详细指导您如何通过WordPress代码二次开发,实现网站访问统计与流量分析功能,并集成常用互联网小工具,打造一个功能全面、自主可控的网站生态系统。
第一部分:环境准备与基础架构设计
1.1 开发环境搭建
在开始二次开发前,需要确保您的环境满足以下条件:
- WordPress安装:建议使用最新版本的WordPress(5.8+)
- 本地开发环境:推荐使用Local by Flywheel、XAMPP或MAMP
- 代码编辑器:VS Code、PHPStorm或Sublime Text
- 数据库管理工具:phpMyAdmin或Adminer
- 版本控制系统:Git(可选但推荐)
1.2 创建自定义插件架构
为了避免主题更新导致代码丢失,我们将通过创建独立插件的方式实现功能:
<?php
/**
* Plugin Name: 自定义网站统计与小工具套件
* Plugin URI: https://yourwebsite.com/
* Description: 自定义网站访问统计、流量分析及常用小工具集成
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('CUSTOM_STATS_VERSION', '1.0.0');
define('CUSTOM_STATS_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('CUSTOM_STATS_PLUGIN_URL', plugin_dir_url(__FILE__));
// 初始化插件
require_once CUSTOM_STATS_PLUGIN_DIR . 'includes/class-core.php';
require_once CUSTOM_STATS_PLUGIN_DIR . 'includes/class-database.php';
require_once CUSTOM_STATS_PLUGIN_DIR . 'includes/class-tracker.php';
// 启动插件
function custom_stats_init() {
$core = new Custom_Stats_Core();
$core->run();
}
add_action('plugins_loaded', 'custom_stats_init');
1.3 数据库表设计
创建专门的数据表来存储访问统计信息:
// includes/class-database.php
class Custom_Stats_Database {
public function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_name = $wpdb->prefix . 'custom_visits';
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id bigint(20) NOT NULL AUTO_INCREMENT,
session_id varchar(64) NOT NULL,
user_id bigint(20) DEFAULT NULL,
ip_address varchar(45) DEFAULT NULL,
user_agent text,
referrer text,
landing_page varchar(512) NOT NULL,
exit_page varchar(512) DEFAULT NULL,
page_views int(11) DEFAULT 1,
visit_duration int(11) DEFAULT 0,
country_code varchar(2) DEFAULT NULL,
city varchar(100) DEFAULT NULL,
device_type varchar(20) DEFAULT NULL,
browser varchar(50) DEFAULT NULL,
os varchar(50) DEFAULT NULL,
screen_resolution varchar(20) DEFAULT NULL,
is_new_visit tinyint(1) DEFAULT 1,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY session_id (session_id),
KEY user_id (user_id),
KEY created_at (created_at),
KEY country_code (country_code),
KEY device_type (device_type)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
// 创建页面访问详情表
$page_views_table = $wpdb->prefix . 'custom_page_views';
$sql2 = "CREATE TABLE IF NOT EXISTS $page_views_table (
id bigint(20) NOT NULL AUTO_INCREMENT,
visit_id bigint(20) NOT NULL,
page_url varchar(512) NOT NULL,
page_title varchar(255) DEFAULT NULL,
time_on_page int(11) DEFAULT 0,
scroll_depth int(3) DEFAULT 0,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY visit_id (visit_id),
KEY page_url (page_url(191))
) $charset_collate;";
dbDelta($sql2);
}
public function update_tables() {
// 未来版本更新时修改表结构
}
}
第二部分:核心访问统计功能实现
2.1 访问数据追踪器
创建主追踪器类,负责收集和存储访问数据:
// includes/class-tracker.php
class Custom_Stats_Tracker {
private $db;
private $session_id;
private $current_visit_id;
public function __construct() {
global $wpdb;
$this->db = $wpdb;
$this->init_session();
}
private function init_session() {
if (!session_id()) {
session_start();
}
if (!isset($_SESSION['custom_stats_session_id'])) {
$_SESSION['custom_stats_session_id'] = $this->generate_session_id();
}
$this->session_id = $_SESSION['custom_stats_session_id'];
}
private function generate_session_id() {
return md5(uniqid(mt_rand(), true) . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']);
}
public function track_visit() {
// 检查是否为机器人或排除的IP
if ($this->is_excluded()) {
return;
}
$current_url = $this->get_current_url();
$referrer = $this->get_referrer();
// 检查是否为新访问
$is_new_visit = $this->is_new_visit();
if ($is_new_visit) {
$this->current_visit_id = $this->record_new_visit($current_url, $referrer);
} else {
$this->update_existing_visit($current_url);
}
// 记录页面浏览详情
$this->record_page_view($current_url);
// 设置JavaScript变量用于前端追踪
$this->set_frontend_data();
}
private function is_excluded() {
$excluded_ips = get_option('custom_stats_excluded_ips', []);
$current_ip = $this->get_client_ip();
// 检查IP是否在排除列表中
if (in_array($current_ip, $excluded_ips)) {
return true;
}
// 检查是否为搜索引擎机器人
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
$bots = ['bot', 'crawl', 'spider', 'slurp', 'search', 'archiver'];
foreach ($bots as $bot) {
if (stripos($user_agent, $bot) !== false) {
return true;
}
}
return false;
}
private function get_client_ip() {
$ip_keys = ['HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED',
'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED',
'REMOTE_ADDR'];
foreach ($ip_keys as $key) {
if (array_key_exists($key, $_SERVER) === true) {
foreach (explode(',', $_SERVER[$key]) as $ip) {
$ip = trim($ip);
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) {
return $ip;
}
}
}
}
return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
}
private function get_current_url() {
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https" : "http";
return $protocol . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
private function get_referrer() {
return $_SERVER['HTTP_REFERER'] ?? '';
}
private function is_new_visit() {
$table_name = $this->db->prefix . 'custom_visits';
$query = $this->db->prepare(
"SELECT id FROM $table_name
WHERE session_id = %s
AND DATE(created_at) = CURDATE()
ORDER BY created_at DESC
LIMIT 1",
$this->session_id
);
$result = $this->db->get_var($query);
return empty($result);
}
private function record_new_visit($url, $referrer) {
$table_name = $this->db->prefix . 'custom_visits';
// 获取地理位置信息(简化版,实际应使用IP数据库)
$geo_info = $this->get_geo_info();
// 解析用户代理
$device_info = $this->parse_user_agent();
$data = [
'session_id' => $this->session_id,
'user_id' => get_current_user_id() ?: null,
'ip_address' => $this->get_client_ip(),
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
'referrer' => $referrer,
'landing_page' => $url,
'country_code' => $geo_info['country_code'],
'city' => $geo_info['city'],
'device_type' => $device_info['device_type'],
'browser' => $device_info['browser'],
'os' => $device_info['os'],
'screen_resolution' => $this->get_screen_resolution(),
'is_new_visit' => 1,
'created_at' => current_time('mysql')
];
$this->db->insert($table_name, $data);
return $this->db->insert_id;
}
private function get_geo_info() {
// 简化版,实际应集成MaxMind GeoIP或类似服务
$ip = $this->get_client_ip();
// 本地IP返回空信息
if ($ip === '127.0.0.1' || strpos($ip, '192.168.') === 0) {
return ['country_code' => null, 'city' => null];
}
// 这里可以调用第三方API或本地数据库
// 示例:使用ipapi.co(免费版有限制)
return ['country_code' => null, 'city' => null];
}
private function parse_user_agent() {
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
// 设备类型检测
$device_type = 'desktop';
if (preg_match('/(android|webos|iphone|ipad|ipod|blackberry|windows phone)/i', $user_agent)) {
$device_type = 'mobile';
} elseif (preg_match('/(tablet|ipad|playbook|silk)/i', $user_agent)) {
$device_type = 'tablet';
}
// 浏览器检测
$browser = 'Unknown';
if (preg_match('/MSIE|Trident/i', $user_agent)) {
$browser = 'Internet Explorer';
} elseif (preg_match('/Firefox/i', $user_agent)) {
$browser = 'Firefox';
} elseif (preg_match('/Chrome/i', $user_agent)) {
$browser = 'Chrome';
} elseif (preg_match('/Safari/i', $user_agent)) {
$browser = 'Safari';
} elseif (preg_match('/Edge/i', $user_agent)) {
$browser = 'Edge';
} elseif (preg_match('/Opera|OPR/i', $user_agent)) {
$browser = 'Opera';
}
// 操作系统检测
$os = 'Unknown';
if (preg_match('/Windows NT 10.0/i', $user_agent)) {
$os = 'Windows 10';
} elseif (preg_match('/Windows NT 6.3/i', $user_agent)) {
$os = 'Windows 8.1';
} elseif (preg_match('/Windows NT 6.2/i', $user_agent)) {
$os = 'Windows 8';
} elseif (preg_match('/Windows NT 6.1/i', $user_agent)) {
$os = 'Windows 7';
} elseif (preg_match('/Macintosh|Mac OS X/i', $user_agent)) {
$os = 'macOS';
} elseif (preg_match('/Linux/i', $user_agent)) {
$os = 'Linux';
} elseif (preg_match('/Android/i', $user_agent)) {
$os = 'Android';
} elseif (preg_match('/iPhone|iPad|iPod/i', $user_agent)) {
$os = 'iOS';
}
return [
'device_type' => $device_type,
'browser' => $browser,
'os' => $os
];
}
private function get_screen_resolution() {
// 通过JavaScript获取,这里先返回空值
return '';
}
private function set_frontend_data() {
add_action('wp_footer', function() {
?>
<script>
window.customStats = {
sessionId: '<?php echo esc_js($this->session_id); ?>',
visitId: <?php echo esc_js($this->current_visit_id); ?>,
nonce: '<?php echo wp_create_nonce('custom_stats_nonce'); ?>',
ajaxUrl: '<?php echo admin_url('admin-ajax.php'); ?>'
};
</script>
<?php
});
}
}
2.2 前端JavaScript追踪
创建前端JavaScript文件,用于收集客户端数据:
// assets/js/frontend-tracker.js
(function() {
'use strict';
class FrontendTracker {
constructor() {
this.config = window.customStats || {};
this.pageStartTime = Date.now();
this.maxScrollDepth = 0;
this.init();
}
init() {
this.trackPageView();
this.trackScrollDepth();
this.trackTimeOnPage();
this.trackClicks();
this.trackFormSubmissions();
this.setupBeforeUnload();
}
trackPageView() {
const data = {
action: 'custom_stats_track_pageview',
nonce: this.config.nonce,
visit_id: this.config.visitId,
page_url: window.location.href,
page_title: document.title,
screen_resolution: this.getScreenResolution(),
viewport_size: this.getViewportSize()
};
this.sendRequest(data);
}
trackScrollDepth() {
let scrollCheckTimer;
const checkScrollDepth = () => {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const scrollHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight;
const scrollPercentage = scrollHeight > 0 ? Math.round((scrollTop / scrollHeight) * 100) : 0;
if (scrollPercentage > this.maxScrollDepth) {
this.maxScrollDepth = scrollPercentage;
// 记录25%、50%、75%、100%的关键点
if ([25, 50, 75, 100].includes(scrollPercentage)) {
const data = {
action: 'custom_stats_track_scroll',
nonce: this.config.nonce,
visit_id: this.config.visitId,
scroll_depth: scrollPercentage,
page_url: window.location.href
};
this.sendRequest(data);
}
}
};
window.addEventListener('scroll', () => {
clearTimeout(scrollCheckTimer);
scrollCheckTimer = setTimeout(checkScrollDepth, 100);
});
}
trackTimeOnPage() {
// 定期发送时间更新
setInterval(() => {
const timeOnPage = Math.round((Date.now() - this.pageStartTime) / 1000);
const data = {
action: 'custom_stats_update_time',
nonce: this.config.nonce,
visit_id: this.config.visitId,
time_on_page: timeOnPage
};
this.sendRequest(data);
}, 30000); // 每30秒发送一次
}
trackClicks() {
document.addEventListener('click', (e) => {
const target = e.target;
const link = target.closest('a');
if (link && link.href) {
const data = {
action: 'custom_stats_track_click',
nonce: this.config.nonce,
visit_id: this.config.visitId,
link_url: link.href,
link_text: link.textContent.substring(0, 100),
page_url: window.location.href
};
2.3 AJAX请求处理与数据存储
继续前端JavaScript代码:
// 如果是外部链接,立即发送数据
if (this.isExternalLink(link.href)) {
this.sendRequest(data, true); // 同步发送
} else {
this.sendRequest(data);
}
}
});
}
trackFormSubmissions() {
document.addEventListener('submit', (e) => {
const form = e.target;
const formId = form.id || form.name || 'unknown';
const data = {
action: 'custom_stats_track_form',
nonce: this.config.nonce,
visit_id: this.config.visitId,
form_id: formId,
form_action: form.action,
page_url: window.location.href
};
this.sendRequest(data);
});
}
setupBeforeUnload() {
window.addEventListener('beforeunload', () => {
const timeOnPage = Math.round((Date.now() - this.pageStartTime) / 1000);
const data = {
action: 'custom_stats_track_exit',
nonce: this.config.nonce,
visit_id: this.config.visitId,
time_on_page: timeOnPage,
scroll_depth: this.maxScrollDepth,
exit_page: window.location.href
};
// 使用navigator.sendBeacon进行可靠的离开页面数据发送
this.sendBeacon(data);
});
}
sendRequest(data, sync = false) {
const formData = new FormData();
for (const key in data) {
formData.append(key, data[key]);
}
if (sync) {
// 同步请求(用于离开页面时)
const xhr = new XMLHttpRequest();
xhr.open('POST', this.config.ajaxUrl, false);
xhr.send(formData);
} else {
// 异步请求
fetch(this.config.ajaxUrl, {
method: 'POST',
body: formData,
keepalive: true // 允许在页面卸载后继续发送
}).catch(error => {
console.error('Tracking error:', error);
});
}
}
sendBeacon(data) {
const blob = new Blob([JSON.stringify(data)], {type: 'application/json'});
navigator.sendBeacon(this.config.ajaxUrl + '?action=custom_stats_track_exit', blob);
}
getScreenResolution() {
return window.screen.width + 'x' + window.screen.height;
}
getViewportSize() {
return window.innerWidth + 'x' + window.innerHeight;
}
isExternalLink(url) {
const currentHost = window.location.hostname;
const linkHost = (new URL(url, window.location.href)).hostname;
return linkHost !== currentHost && linkHost !== '';
}
}
// 初始化追踪器
document.addEventListener('DOMContentLoaded', () => {
if (window.customStats) {
new FrontendTracker();
}
});
})();
2.4 PHP端AJAX处理
创建AJAX请求处理类:
// includes/class-ajax-handler.php
class Custom_Stats_Ajax_Handler {
private $db;
public function __construct() {
global $wpdb;
$this->db = $wpdb;
$this->register_ajax_actions();
}
private function register_ajax_actions() {
// 页面浏览追踪
add_action('wp_ajax_custom_stats_track_pageview', [$this, 'handle_pageview']);
add_action('wp_ajax_nopriv_custom_stats_track_pageview', [$this, 'handle_pageview']);
// 滚动深度追踪
add_action('wp_ajax_custom_stats_track_scroll', [$this, 'handle_scroll']);
add_action('wp_ajax_nopriv_custom_stats_track_scroll', [$this, 'handle_scroll']);
// 点击追踪
add_action('wp_ajax_custom_stats_track_click', [$this, 'handle_click']);
add_action('wp_ajax_nopriv_custom_stats_track_click', [$this, 'handle_click']);
// 表单提交追踪
add_action('wp_ajax_custom_stats_track_form', [$this, 'handle_form']);
add_action('wp_ajax_nopriv_custom_stats_track_form', [$this, 'handle_form']);
// 退出页面追踪
add_action('wp_ajax_custom_stats_track_exit', [$this, 'handle_exit']);
add_action('wp_ajax_nopriv_custom_stats_track_exit', [$this, 'handle_exit']);
// 时间更新
add_action('wp_ajax_custom_stats_update_time', [$this, 'update_time']);
add_action('wp_ajax_nopriv_custom_stats_update_time', [$this, 'update_time']);
}
public function handle_pageview() {
$this->verify_nonce();
$visit_id = intval($_POST['visit_id']);
$page_url = sanitize_text_field($_POST['page_url']);
$page_title = sanitize_text_field($_POST['page_title']);
$screen_resolution = sanitize_text_field($_POST['screen_resolution']);
$table_name = $this->db->prefix . 'custom_page_views';
$data = [
'visit_id' => $visit_id,
'page_url' => $page_url,
'page_title' => $page_title,
'created_at' => current_time('mysql')
];
// 更新访问记录中的屏幕分辨率
if (!empty($screen_resolution)) {
$visits_table = $this->db->prefix . 'custom_visits';
$this->db->update(
$visits_table,
['screen_resolution' => $screen_resolution],
['id' => $visit_id]
);
}
$this->db->insert($table_name, $data);
wp_die('1');
}
public function handle_scroll() {
$this->verify_nonce();
$visit_id = intval($_POST['visit_id']);
$scroll_depth = intval($_POST['scroll_depth']);
$page_url = sanitize_text_field($_POST['page_url']);
$table_name = $this->db->prefix . 'custom_page_views';
// 找到当前页面的最新记录并更新滚动深度
$this->db->query(
$this->db->prepare(
"UPDATE $table_name
SET scroll_depth = %d
WHERE visit_id = %d
AND page_url = %s
ORDER BY created_at DESC
LIMIT 1",
$scroll_depth,
$visit_id,
$page_url
)
);
wp_die('1');
}
public function handle_click() {
$this->verify_nonce();
$visit_id = intval($_POST['visit_id']);
$link_url = esc_url_raw($_POST['link_url']);
$link_text = sanitize_text_field($_POST['link_text']);
$page_url = sanitize_text_field($_POST['page_url']);
$table_name = $this->db->prefix . 'custom_clicks';
// 创建点击记录表(如果不存在)
$this->create_clicks_table();
$data = [
'visit_id' => $visit_id,
'link_url' => $link_url,
'link_text' => $link_text,
'page_url' => $page_url,
'created_at' => current_time('mysql')
];
$this->db->insert($table_name, $data);
wp_die('1');
}
private function create_clicks_table() {
$table_name = $this->db->prefix . 'custom_clicks';
if ($this->db->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
$charset_collate = $this->db->get_charset_collate();
$sql = "CREATE TABLE $table_name (
id bigint(20) NOT NULL AUTO_INCREMENT,
visit_id bigint(20) NOT NULL,
link_url varchar(512) NOT NULL,
link_text varchar(255) DEFAULT NULL,
page_url varchar(512) NOT NULL,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY visit_id (visit_id),
KEY link_url (link_url(191))
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
}
public function handle_form() {
$this->verify_nonce();
$visit_id = intval($_POST['visit_id']);
$form_id = sanitize_text_field($_POST['form_id']);
$form_action = esc_url_raw($_POST['form_action']);
$page_url = sanitize_text_field($_POST['page_url']);
$table_name = $this->db->prefix . 'custom_form_submissions';
// 创建表单提交表(如果不存在)
$this->create_forms_table();
$data = [
'visit_id' => $visit_id,
'form_id' => $form_id,
'form_action' => $form_action,
'page_url' => $page_url,
'created_at' => current_time('mysql')
];
$this->db->insert($table_name, $data);
wp_die('1');
}
private function create_forms_table() {
$table_name = $this->db->prefix . 'custom_form_submissions';
if ($this->db->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
$charset_collate = $this->db->get_charset_collate();
$sql = "CREATE TABLE $table_name (
id bigint(20) NOT NULL AUTO_INCREMENT,
visit_id bigint(20) NOT NULL,
form_id varchar(100) NOT NULL,
form_action varchar(512) NOT NULL,
page_url varchar(512) NOT NULL,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY visit_id (visit_id),
KEY form_id (form_id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
}
public function handle_exit() {
// 对于sendBeacon请求,数据在php://input中
if ($_SERVER['REQUEST_METHOD'] === 'POST' && empty($_POST)) {
$input = file_get_contents('php://input');
$data = json_decode($input, true);
if ($data) {
$_POST = $data;
}
}
$visit_id = intval($_POST['visit_id']);
$time_on_page = intval($_POST['time_on_page']);
$scroll_depth = intval($_POST['scroll_depth']);
$exit_page = sanitize_text_field($_POST['exit_page']);
$table_name = $this->db->prefix . 'custom_visits';
$this->db->update(
$table_name,
[
'exit_page' => $exit_page,
'visit_duration' => $time_on_page,
'updated_at' => current_time('mysql')
],
['id' => $visit_id]
);
// 更新最后页面的滚动深度
$page_views_table = $this->db->prefix . 'custom_page_views';
$this->db->query(
$this->db->prepare(
"UPDATE $page_views_table
SET scroll_depth = %d
WHERE visit_id = %d
ORDER BY created_at DESC
LIMIT 1",
$scroll_depth,
$visit_id
)
);
wp_die('1');
}
public function update_time() {
$this->verify_nonce();
$visit_id = intval($_POST['visit_id']);
$time_on_page = intval($_POST['time_on_page']);
$table_name = $this->db->prefix . 'custom_visits';
$this->db->update(
$table_name,
[
'visit_duration' => $time_on_page,
'updated_at' => current_time('mysql')
],
['id' => $visit_id]
);
wp_die('1');
}
private function verify_nonce() {
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'custom_stats_nonce')) {
wp_die('Security check failed', 403);
}
}
}
第三部分:数据分析与报表系统
3.1 数据统计类
创建数据统计和报表生成类:
// includes/class-statistics.php
class Custom_Stats_Statistics {
private $db;
public function __construct() {
global $wpdb;
$this->db = $wpdb;
}
public function get_daily_stats($date = null) {
if (!$date) {
$date = current_time('Y-m-d');
}
$visits_table = $this->db->prefix . 'custom_visits';
$page_views_table = $this->db->prefix . 'custom_page_views';
$stats = [
'date' => $date,
'visits' => 0,
'unique_visitors' => 0,
'pageviews' => 0,
'avg_duration' => 0,
'bounce_rate' => 0
];
// 获取总访问数
$stats['visits'] = $this->db->get_var(
$this->db->prepare(
"SELECT COUNT(*) FROM $visits_table WHERE DATE(created_at) = %s",
$date
)
);
// 获取独立访客数
$stats['unique_visitors'] = $this->db->get_var(
$this->db->prepare(
"SELECT COUNT(DISTINCT session_id) FROM $visits_table WHERE DATE(created_at) = %s",
$date
)
);
// 获取总页面浏览量
$stats['pageviews'] = $this->db->get_var(
$this->db->prepare(
"SELECT COUNT(*) FROM $page_views_table pv
INNER JOIN $visits_table v ON pv.visit_id = v.id
WHERE DATE(v.created_at) = %s",
$date
)
);
// 获取平均访问时长
$avg_duration = $this->db->get_var(
$this->db->prepare(
"SELECT AVG(visit_duration) FROM $visits_table
WHERE DATE(created_at) = %s AND visit_duration > 0",
$date
)
);
$stats['avg_duration'] = $avg_duration ? round($avg_duration) : 0;
// 计算跳出率(只浏览一个页面且停留时间短于30秒)
$bounce_count = $this->db->get_var(
$this->db->prepare(
"SELECT COUNT(*) FROM (
SELECT v.id, COUNT(pv.id) as page_count, v.visit_duration
FROM $visits_table v
LEFT JOIN $page_views_table pv ON v.id = pv.visit_id
WHERE DATE(v.created_at) = %s
GROUP BY v.id
HAVING page_count = 1 AND visit_duration < 30
) as bounces",
$date
)
);
if ($stats['visits'] > 0) {
$stats['bounce_rate'] = round(($bounce_count / $stats['visits']) * 100, 2);
}
return $stats;
}
public function get_top_pages($limit = 10, $period = 'today') {
$page_views_table = $this->db->prefix . 'custom_page_views';
$visits_table = $this->db->prefix . 'custom_visits';
$where_clause = $this->get_period_where_clause($period, 'v.created_at');
$query = $this->db->prepare(
"SELECT pv.page_url, pv.page_title,
COUNT(pv.id) as views,
COUNT(DISTINCT v.session_id) as unique_visitors,
AVG(pv.scroll_depth) as avg_scroll_depth,
AVG(v.visit_duration) as avg_time_on_page
FROM $page_views_table pv
INNER JOIN $visits_table v ON pv.visit_id = v.id
WHERE 1=1 $where_clause
GROUP BY pv.page_url
ORDER BY views DESC
LIMIT %d",
$limit
);
return $this->db->get_results($query);
}
public function get_traffic_sources($period = 'today') {
$visits_table = $this->db->prefix . 'custom_visits';
$where_clause = $this->get_period_where_clause($period);
$query = "SELECT
CASE
WHEN referrer = '' THEN '直接访问'
WHEN referrer LIKE '%' || %s || '%' THEN '内部链接'
WHEN referrer LIKE '%google.%' THEN 'Google'
WHEN referrer LIKE '%bing.%' THEN 'Bing'
WHEN referrer LIKE '%baidu.%' THEN '百度'
WHEN referrer LIKE '%yahoo.%' THEN 'Yahoo'
WHEN referrer LIKE '%facebook.%' THEN 'Facebook'
WHEN referrer LIKE '%twitter.%' THEN 'Twitter'
WHEN referrer LIKE '%linkedin.%' THEN 'LinkedIn'
ELSE '其他推荐'
END as source,
COUNT(*) as visits,
COUNT(DISTINCT session_id) as unique_visitors,
AVG(visit_duration) as avg_duration
FROM $visits_table
