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

PHP IP 黑名單與 IP 段封禁實作類

     編輯:PHP 綜合知識

支援多種格式的 IP 封禁類

支援單一 IP、通配符、範圍、列舉等多種格式:

  • 192.168.1.1 單一 IP
  • 192.168.1.* 等同 192.168.1.1-255
  • 192.168.1.2-20 範圍
  • 192.168.1.[1|2|3] 列舉

完整類別程式碼

<?php
class BlockIP {
    private $blockList = array("192.168.1.1", "210.10.2.1-20", "222.34.4.*");

    public function __construct() {}
    public function __destruct() {}

    // 將單段轉為正則片段
    private function makePregSegment($seg) {
        if (strpos($seg, '-') !== false) {
            list($from, $to) = explode('-', $seg);
            $parts = array();
            for ($i = $from; $i <= $to; $i++) {
                $parts[] = $i;
            }
            return '(' . implode('|', $parts) . ')';
        } elseif ($seg == '*') {
            return '[0-9]{1,3}';
        } else {
            return $seg;
        }
    }

    // 將完整 IP 規則轉為正則
    private function ruleToRegex($rule) {
        $segments = explode('.', $rule);
        $regexSegs = array();
        foreach ($segments as $seg) {
            if (strpos($seg, '[') === 0) { // 已是列舉格式 [1|2|3]
                $inner = trim($seg, '[]');
                $options = explode('|', $inner);
                $regexSegs[] = '(' . implode('|', $options) . ')';
            } else {
                $regexSegs[] = $this->makePregSegment($seg);
            }
        }
        return '/^' . implode('\.', $regexSegs) . '$/';
    }

    // 建立所有封禁正則
    private function getAllRegex() {
        $regexes = array();
        foreach ($this->blockList as $rule) {
            $regexes[] = $this->ruleToRegex($rule);
        }
        return $regexes;
    }

    // 取得客戶端真實 IP
    private function getClientIP() {
        $headers = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR');
        foreach ($headers as $h) {
            $val = isset($_SERVER[$h]) ? $_SERVER[$h] : (function_exists('getenv') ? getenv($h) : '');
            if ($val && strcasecmp($val, 'unknown') !== 0) {
                // 可能包含多個 IP,取第一個
                $ips = explode(',', $val);
                return trim($ips[0]);
            }
        }
        return 'unknown';
    }

    // 公開檢查方法
    public function checkIP() {
        $ip = $this->getClientIP();
        if ($ip === 'unknown') return; // 無法判斷則放行

        foreach ($this->getAllRegex() as $regex) {
            if (preg_match($regex, $ip)) {
                header("HTTP/1.1 403 Forbidden");
                exit('IP Forbidden');
            }
        }
    }
}

// 使用方式
$blocker = new BlockIP();
$blocker->checkIP();
?>

改良重點

  • 修正原碼中 makePregIP 邏輯錯誤與變數未定義問題。
  • 支援 [1|2|3] 列舉語法。
  • 正則預編譯,效能更好。
  • 自動處理 X-Forwarded-For 多 IP 情況。
  • 回傳 403 狀態碼,利於 SEO 與日誌分析。

擴充建議

  1. 將封禁清單移至資料庫或配置檔,支援動態更新。
  2. 加入白名單機制(優先於黑名單)。
  3. 記錄封鎖日誌(IP、時間、規則)。
  4. 支援 CIDR 表示法(如 192.168.1.0/24)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved