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

PHP 簡易計數器實作與安全性改良

     編輯:PHP 相關知識

PHP 簡易計數器實作與安全性改良

計數器是網站常見功能,用於統計頁面瀏覽次數。本文提供一個以文字檔儲存計數的基礎範例,並針對原始碼的安全性問題提出改良建議。

原始實作程式碼

<?php
$counterFile = "balong.txt"; // 計數儲存檔案

function displayCounter($counterFile) {
    $fp = fopen($counterFile, "rw");
    $num = fgets($fp, 5);
    $num += 1;
    print "您是第 " . $num . " 個看巴泷計數器的家伙";
    
    // 危險:直接執行系統指令刪除與寫入檔案
    exec("rm -rf $counterFile");
    exec("echo $num > $counterFile");
}

if (!file_exists($counterFile)) {
    exec("echo 0 > $counterFile");
}

displayCounter($counterFile);
?>

安全性風險分析

  • 命令注入風險:exec() 直接使用變數未經過濾,若檔案路徑可被控制,攻擊者可執行任意指令
  • 競態條件:讀取、刪除、寫入非原子操作,高併發下計數會遺失
  • 權限問題:需要目錄寫入權限,且執行 rm -rf 極度危險
  • 檔案鎖定缺失:多進程同時存取會導致資料損毀

改良版:安全、高效的計數器

<?php
$counterFile = __DIR__ . "/data/counter.txt";

// 確保資料目錄存在且不可直接網路存取
if (!is_dir(dirname($counterFile))) {
    mkdir(dirname($counterFile), 0750, true);
}

// 使用檔案鎖定確保原子性
$fp = fopen($counterFile, "c+"); // 開啟讀寫,不存在則建立
if ($fp && flock($fp, LOCK_EX)) { // 獨佔鎖定
    $num = (int)fgets($fp, 20);
    $num++;
    
    ftruncate($fp, 0); // 清空檔案
    rewind($fp);
    fwrite($fp, (string)$num);
    fflush($fp);
    flock($fp, LOCK_UN); // 釋放鎖定
    fclose($fp);
    
    echo "您是第 {$num} 位訪客";
} else {
    echo "計數器暫時無法使用";
}
?>

進階優化方向

方案優點適用場景
資料庫計數器支援高併發、可關聯分析維度中大型網站
Redis/Memcached極高效能、支援原子遞增高流量系統
Google Analytics免維運、豐富報表不需自建統計
靜態頁面+JS 非同步統計不影響頁面載入速度靜態網站

最佳實踐總結

  1. 避免使用 exec()、system() 等系統指令函數
  2. 檔案操作務必加鎖(flock())
  3. 計數資料存放於公開目錄外
  4. 考慮使用資料庫或快取系統替代文字檔
  5. 前端顯示可採非同步載入,不阻塞頁面渲染

簡單的計數器看似容易,但涉及並發控制、資料一致性與安全性等核心議題,是檢驗後端工程師基本功的好題目。

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