在 Web 開發中,防止用戶重複刷新頁面或重複提交表單是常見需求。本文介紹一種基於 PHP Session 結合 IP 地址與提交參數的防重複刷新機制,適用於表單提交、支付回調等場景。
該方案的核心邏輯如下:
<?php
// 僅允許 POST 方式訪問
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
header('HTTP/1.1 404 Not Found');
die('親,頁面不存在');
}
session_start();
// 獲取表單提交參數
$fs1 = $_POST['a'];
$fs2 = $_POST['b'];
// 防刷新時間間隔(秒)
$allowTime = 30;
/**
* 獲取客戶端真實 IP
*/
function GetIP() {
static $ip = NULL;
if ($ip !== NULL) return $ip;
if (isset($_SERVER)) {
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
foreach ($arr as $xip) {
$xip = trim($xip);
if ($xip != 'unknown') {
$ip = $xip;
break;
}
}
} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} else {
$ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
}
} else {
if (getenv('HTTP_X_FORWARDED_FOR')) {
$ip = getenv('HTTP_X_FORWARDED_FOR');
} elseif (getenv('HTTP_CLIENT_IP')) {
$ip = getenv('HTTP_CLIENT_IP');
} else {
$ip = getenv('REMOTE_ADDR');
}
}
preg_match("/[\d\.]{7,15}/", $ip, $onlineip);
$ip = !empty($onlineip[0]) ? $onlineip[0] : '0.0.0.0';
return $ip;
}
$reip = GetIP();
// 生成唯一標識:IP + 參數 MD5
$allowT = md5($reip . $fs1 . $fs2);
if (!isset($_SESSION[$allowT])) {
$_SESSION[$allowT] = time();
} elseif (time() - $_SESSION[$allowT] > $allowTime) {
$_SESSION[$allowT] = time();
} else {
header('HTTP/1.1 404 Not Found');
die('來自 ' . $ip . ' 的親,您刷新過快了');
}
?>
對應的 HTML 表單頁面(a.html):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>提交頁面</title>
</head>
<body>
<form action="b.php" method="post">
<input type="hidden" id="a" name="a" value="a"/>
<input type="hidden" id="b" name="b" value="b"/>
<button type="submit">提交</button>
</form>
</body>
</html>
適用於表單提交、支付回調、投票等需防重複操作的場景。注意:Session 依賴 Cookie,若用戶禁用 Cookie 則失效;分佈式環境需共享 Session 儲存(如 Redis)。生產環境建議結合資料庫唯一索引或分佈式鎖實現更可靠的冪等性保障。