首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 下載計數器:中介頁面實現點擊數即時回寫

     編輯:PHP 綜合知識

需求場景

提供檔案下載連結時,需統計每個檔案的下載次數。直接連結無法攔截請求,故引入中介頁面 ddload.php:記錄計數後再導向真實下載網址。

資料表結構

CREATE TABLE book (
    id INT PRIMARY KEY AUTO_INCREMENT,
    downnum INT DEFAULT 0  -- 下載次數
    -- 其他欄位:檔名、路徑、描述等
);

兩支程式碼

1. 列表頁 (first.php) - 顯示計數與產生下載連結

<?php while ($myrow = mysql_fetch_array($result)) { ?>
<tr>
  <td><?= empty($myrow['downnum']) ? 0 : $myrow['downnum'] ?></td>
  <td>
    <a href="ddload.php?purl=<?= urlencode($myrow['fileurl']) ?>&dnnum=<?= $myrow['downnum'] ?>&id=<?= $myrow['id'] ?>">
      點此下載
    </a>
  </td>
</tr>
<?php } ?>

2. 中介處理頁 (ddload.php) - 更新計數並重導向

<?php
include("data.inc.php"); // 資料庫連線設定
if ($incerror) { echo $incerror; exit; }

$dnnum = empty($dnnum) ? 1 : $dnnum + 1;
$sql = "UPDATE book SET downnum = '$dnnum' WHERE id = $id";
mysql_query($sql);
mysql_close($connect);

header("Location: $purl"); // 重導向至真實檔案
?>

安全與邏輯漏洞分析

問題風險修正
直接信任 $id, $dnnum 參數SQL Injection、計數竄改PDO 預處理、intval() 強制整數
計數邏輯競態條件高併發下計數遺漏UPDATE book SET downnum = downnum + 1 WHERE id = ? 原子操作
導向目標 $purl 未驗證開放式重導向攻擊白名單驗證、或僅允許本站路徑
使用 mysql_* 已移除函式PHP 7+ 不可用遷移至 PDO / MySQLi
無下載完成確認用戶取消下載仍計數前端 JS 回報 / 伺服端檢查 Content-Length 傳輸完成

改進版核心邏輯 (PDO + 原子更新)

<?php
// ddload_v2.php
require_once 'pdo_config.php';
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
$purl = isset($_GET['purl']) ? $_GET['purl'] : '';

if (!$id || !$purl) { http_response_code(400); exit('參數錯誤'); }

// 白名單驗證:確保 purl 指向本站允許目錄
$allowedBase = 'https://mysite.com/downloads/';
if (strpos($purl, $allowedBase) !== 0) { http_response_code(403); exit('非法下載連結'); }

try {
    $stmt = $pdo->prepare("UPDATE book SET downnum = downnum + 1 WHERE id = ?");
    $stmt->execute([$id]);
    header("Location: $purl");
} catch (PDOException $e) {
    error_log($e->getMessage());
    http_response_code(500); exit('系統錯誤');
}
?>

進階擴展:非同步記錄與快取

  • Redis 計數器:INCR download:{id} 極速計數,定期同步落地 MySQL。
  • 非同步隊列:請求寫入 Kafka/RabbitMQ,消費者批次更新資料庫,降低寫入壓力。
  • 防刷機制:同 IP + 同檔案 在 N 秒內僅計數一次(Redis Set + TTL)。

總結

中介頁面模式是下載計數的經典解法。核心在於「原子更新計數」與「安全重導向」。現代架構可引入 Redis 快取層與非同步隊列,支撐百萬級下載統計。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved