PHP防重推荐实现
PHP防重推荐实现
基于数据库的唯一索引
在数据库中为需要防重的字段添加唯一索引,确保数据唯一性。例如用户注册时防止重复用户名:
ALTER TABLE users ADD UNIQUE INDEX (username);
PHP插入数据时捕获唯一键冲突异常:
try {
$stmt = $pdo->prepare("INSERT INTO users (username) VALUES (?)");
$stmt->execute([$username]);
} catch (PDOException $e) {
if ($e->errorInfo[1] == 1062) {
echo "用户名已存在";
}
}
Redis原子操作防重
利用Redis的SETNX命令实现分布式锁,适合高并发场景:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$key = 'user_register:' . $username;
if ($redis->setnx($key, 1)) {
$redis->expire($key, 300); // 设置5分钟过期
// 执行核心业务逻辑
} else {
echo "操作过于频繁,请稍后重试";
}
布隆过滤器实现
对于海量数据去重,可使用布隆过滤器减少数据库查询:
// 使用phpbloom库示例
require_once 'BloomFilter.php';
$bf = new BloomFilter(1000000, 0.01);
if ($bf->has($item)) {
echo "内容已存在";
} else {
$bf->add($item);
// 写入数据库
}
文件哈希校验
文件上传防重可通过计算文件哈希值实现:
$fileHash = md5_file($_FILES['file']['tmp_name']);
$stmt = $pdo->prepare("SELECT COUNT(*) FROM files WHERE file_hash = ?");
$stmt->execute([$fileHash]);
if ($stmt->fetchColumn() > 0) {
echo "相同文件已存在";
}
客户端Token机制
表单提交防重复可通过Token实现:
// 生成Token
$token = bin2hex(random_bytes(32));
$_SESSION['form_token'] = $token;
// 验证Token
if ($_POST['token'] !== $_SESSION['form_token']) {
die("重复提交禁止");
}
unset($_SESSION['form_token']);
时间窗口限制
对API接口实现时间窗口防重:
$redisKey = 'api_limit:' . $userId;
$current = time();
$window = 60; // 60秒窗口
if ($redis->zCount($redisKey, $current - $window, $current) > 0) {
http_response_code(429);
exit;
}
$redis->zAdd($redisKey, $current, $current);
$redis->expire($redisKey, $window);






