时间:2025年2月27日 浏览量:Loading…
一直以来,想给网页加上一个浏览量统计访问次数,正好今天小朋友忙着画画,自己抽时间来完成这个事情。这里想通过一个网页浏览量统计系统,并通过数据库MySQL来实现存储和读取。
简单的网页可能只需要统计访问量。若是想对访问量做进一步分析,可以存储更多的信息,比如访问IP地址、客户端、HTTP来源等。以下是创建表格的shema文件create_tables.sql
-- Table to store aggregated page view data; create this table first --
CREATE TABLE page_views (
page_url VARCHAR(255) NOT NULL PRIMARY KEY, -- unique url
view_count INT DEFAULT 0, -- total view count
unique_ip_count INT DEFAULT 0, -- unique ip count
unique_user_agent_count INT DEFAULT 0, -- browser, device, OS, engine, etc.
unique_referrer_count INT DEFAULT 0, -- HTTP Referer
last_view TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- Table to store unique IP addresses per page --
CREATE TABLE page_view_ips (
page_url VARCHAR(255) NOT NULL, -- page url
ip_address VARCHAR(45) NOT NULL, -- unique IP address
view_count INT DEFAULT 1, -- number of views from an IP
PRIMARY KEY (page_url, ip_address), -- ensures each IP is only stored once per page
FOREIGN KEY (page_url) REFERENCES page_views(page_url) ON DELETE CASCADE -- deletes IP records if the page is removed
);
-- Table to store unique User-Agent views with a count --
CREATE TABLE page_view_user_agents (
page_url VARCHAR(255) NOT NULL, -- Page URL
user_agent VARCHAR(255) NOT NULL, -- Unique User-Agent string
view_count INT DEFAULT 1, -- Number of views from this User-Agent
PRIMARY KEY (page_url, user_agent), -- Prevents duplicate entries per page
FOREIGN KEY (page_url) REFERENCES page_views(page_url) ON DELETE CASCADE -- Cascades deletion
);
-- Table to store unique Referrer views with a count --
CREATE TABLE page_view_referrers (
page_url VARCHAR(255) NOT NULL, -- Page URL
referrer VARCHAR(255) NOT NULL, -- Unique Referrer URL
view_count INT DEFAULT 1, -- Number of views from this Referrer
PRIMARY KEY (page_url, referrer), -- Prevents duplicate entries per page
FOREIGN KEY (page_url) REFERENCES page_views(page_url) ON DELETE CASCADE -- Cascades deletion
);
在MySQL运行的情况下,执行:
mysql -u your_username -p -D your_database_name < create_tables.sql
这里创建了一个PHP处理页面文件track_views.php
,以便获取当前URL、检查更新数据库、并返回浏览量。同时,为了避免一些重复统计,对可能的同一访问做了限制。
<?php
// ======== Configurations ========
$rate_limit_time = 60; // seconds per request from the same IP + User-Agent
// ======== Database connection ========
$env = parse_ini_file('/var/www/config/.env');
$servername = $env['DB_HOST'];
$username = $env['DB_USER'];
$password = $env['DB_PASSWORD'];
$dbname = $env['DB_NAME'];
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// ======== Communicate with database ========
session_start(); // Use session to store rate-limit cache
// Detect the correct page URL:
if (isset($_SERVER['HTTP_REFERER']) && !empty($_SERVER['HTTP_REFERER'])) {
$page_url = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_PATH); // Get the referring page path
else {
} $page_url = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); // Get the current PHP file path
}
// Ensure the page_url always starts with a single leading slash
$page_url = '/' . ltrim($page_url, '/');
// Include the full domain in the page URL
$page_url = $_SERVER['HTTP_HOST'] . $page_url;
$page_url = $conn->real_escape_string($page_url); // Prevent SQL injection
// Get user details
$ip_address = $_SERVER['REMOTE_ADDR'] === '::1' ? '127.0.0.1' : $_SERVER['REMOTE_ADDR'];
$ip_address = $conn->real_escape_string($ip_address);
$user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $conn->real_escape_string($_SERVER['HTTP_USER_AGENT']) : 'Unknown';
$referrer = isset($_SERVER['HTTP_REFERER']) ? $conn->real_escape_string($_SERVER['HTTP_REFERER']) : '';
$hash_key = md5($ip_address . $user_agent); // Create a unique hash for the user
// ======== Fetch Latest View Count Before Rate Limiting ========
$result = $conn->query("SELECT view_count FROM page_views WHERE page_url = '$page_url'");
$row = $result->fetch_assoc();
$current_view_count = $row ? $row['view_count'] : 1;
// ======== Rate Limiting (Prevent Excessive DB Writes) ========
if (isset($_SESSION['last_request'][$hash_key]) && (time() - $_SESSION['last_request'][$hash_key]) < $rate_limit_time) {
echo $current_view_count;
$conn->close();
exit();
}$_SESSION['last_request'][$hash_key] = time(); // Update last request timestamp
// ======== Database Update ========
$conn->begin_transaction();
// -- Update Total View Count --
$conn->query("
INSERT INTO page_views (page_url, view_count)
VALUES ('$page_url', 1)
ON DUPLICATE KEY UPDATE view_count = view_count + 1
");
// -- Update Unique IP Count --
$conn->query("
INSERT INTO page_view_ips (page_url, ip_address, view_count)
VALUES ('$page_url', '$ip_address', 1)
ON DUPLICATE KEY UPDATE view_count = view_count + 1
");
// Increment unique IP count only for first-time visits
$conn->query("
UPDATE page_views
SET unique_ip_count = unique_ip_count + 1
WHERE page_url = '$page_url'
AND NOT EXISTS (SELECT 1 FROM page_view_ips WHERE page_url = '$page_url' AND ip_address = '$ip_address')
");
// -- Update Unique User-Agent Count --
$conn->query("
INSERT INTO page_view_user_agents (page_url, user_agent, view_count)
VALUES ('$page_url', '$user_agent', 1)
ON DUPLICATE KEY UPDATE view_count = view_count + 1
");
// Increment unique user-agent count only for first-time visits
$conn->query("
UPDATE page_views
SET unique_user_agent_count = unique_user_agent_count + 1
WHERE page_url = '$page_url'
AND NOT EXISTS (SELECT 1 FROM page_view_user_agents WHERE page_url = '$page_url' AND user_agent = '$user_agent')
");
// -- Update Unique Referrer Count --
if (!empty($referrer)) {
$conn->query("
INSERT INTO page_view_referrers (page_url, referrer, view_count)
VALUES ('$page_url', '$referrer', 1)
ON DUPLICATE KEY UPDATE view_count = view_count + 1
");
// Increment unique referrer count only for first-time visits
$conn->query("
UPDATE page_views
SET unique_referrer_count = unique_referrer_count + 1
WHERE page_url = '$page_url'
AND NOT EXISTS (SELECT 1 FROM page_view_referrers WHERE page_url = '$page_url' AND referrer = '$referrer')
");
}
// Commit transaction
$conn->commit();
// ======== Results from database ========
// Fetch latest view count
$result = $conn->query("SELECT view_count FROM page_views WHERE page_url = '$page_url'");
$row = $result->fetch_assoc();
echo $row ? $row['view_count'] : 1;
$conn->close();
?>
为了保证MySQL数据库的安全访问,可将相关信息存储在/var/www/config/.env
的文件里。
DB_HOST=localhost
DB_USER=username
DB_PASSWORD=password
DB_NAME=database
在网页.html
文件的head
里面通过JavaScript加载PHP页面处理文件。
<script>
document.addEventListener("DOMContentLoaded", function() {
fetch('/track_views.php', { credentials: 'include' })
.then(response => response.text())
.then(viewCount => {
console.log("Page View Count:", viewCount);
let viewElement = document.getElementById("page-views");
if (viewElement) {
.textContent = "浏览量: " + viewCount;
viewElement
}
}) .catch(error => console.error("Error fetching page views:", error));
;
})</script>
同时,在HTML页面中显示浏览量:
<p id="page-views" style="text-align: center; font-size: 20px; font-weight: bold; margin-top: 20px;">浏览量:Loading...</p>
为了使以上PHP页面处理可以正常工作,要确保php
server是运行的。对于本地的测试,php已经安装运行,可以采用:
php -S localhost:8000
比如,对于同一文件夹下的index.html
文件,可在浏览器中打开:
<http://localhost:8000/index.html
对于远端网页server上的测试,要确保/var/www/config/.env
可以被server自身访问,但要保护其信息不被泄露。
此外,要结合数据库里的存储信息,检验是否正确存储和读取。以上网页浏览量统计系统适用于多个页面的访问统计。