首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

PHP + MySQL + GD 實現防刷新圖形計數器

     編輯:MySQL 資料庫相關知識

雙表設計防刷新

  • hit_count:單行單列存總計數
  • page_visit_record:記錄 IP+日期+頁面,同一天同 IP 同頁面只計一次
CREATE TABLE hit_count (hit_count INT NOT NULL DEFAULT 0);
CREATE TABLE page_visit_record (
    visit_time DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
    remote_addr CHAR(15) NOT NULL,
    visit_page CHAR(60) NOT NULL,
    KEY idx_visit (visit_time, visit_page),
    PRIMARY KEY (visit_time)
);

核心 PHP 邏輯

<?php
include("config.inc.php");
$db = mysql_connect($host, $user, $pass);
mysql_select_db($dbname, $db);

// 1. 檢查今日是否已計數
$ip = $_SERVER['REMOTE_ADDR'];
$today = date('Y-m-d');
$sql = "SELECT COUNT(*) AS cnt FROM page_visit_record 
        WHERE remote_addr='$ip' AND DATE(visit_time)='$today'";
$res = mysql_query($sql, $db);
$row = mysql_fetch_assoc($res);
$has_count = $row['cnt'];

// 2. 更新總計數 (表鎖防併發)
mysql_query("LOCK TABLES hit_count WRITE", $db);
$res = mysql_query("SELECT hit_count FROM hit_count", $db);
if (mysql_num_rows($res) > 0) {
    $cur = mysql_result($res, 0, 'hit_count');
    if ($has_count == 0) {
        $cur++;
        mysql_query("UPDATE hit_count SET hit_count=$cur", $db);
    }
} else {
    $cur = 1;
    mysql_query("INSERT INTO hit_count VALUES (1)", $db);
}
mysql_query("UNLOCK TABLES", $db);

// 3. 記錄訪問日誌
$visit_time = date('Y-m-d H:i:s');
$page = $_SERVER['REQUEST_URI'];
mysql_query("INSERT INTO page_visit_record VALUES ('$visit_time', '$ip', '$page')", $db);

// 4. 輸出 GIF 圖片
header("Content-type: image/gif");
$im = imagecreate(56, 16);
$black = imagecolorallocate($im, 0, 0, 0);
$white = imagecolorallocate($im, 255, 255, 255);
$num_str = sprintf("%08d", $cur); // 8 位補零
imagestring($im, 5, 2, 0, $num_str, $white);
imagegif($im);
imagedestroy($im);
mysql_close($db);
?>

關鍵點解析

  1. 表鎖:LOCK TABLES ... WRITE 保證計數器原子性,避免併發丟更新
  2. 防刷新:複合唯一鍵 (IP + 日期 + 頁面) 可替代表鎖,更高效
  3. GD 繪圖:imagecreate 創建畫布,imagestring 寫文本,imagegif 輸出
  4. 補零格式化:sprintf("%08d", $num) 保證圖片寬度固定

現代化改造建議

  • 使用 mysqli/PDO + 準備語句防注入
  • 計數器改用 Redis INCR + Lua 腳本原子操作,性能提升 100 倍
  • 防刷新用 Redis Set 存 ip:date:page 並設置 24h 過期
  • 圖片輸出改用 imagepng + 透明背景,或直接前端 JS 顯示數字
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved