PHP商城装扮系统装备物品前校验用户所有权的实现咨询
实现方案
前提准备
你需要先在数据库中创建用户持有物品的关联表(如果还没有的话),表结构参考:
CREATE TABLE `user_items` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL COMMENT '关联用户ID', `item_id` int(11) NOT NULL COMMENT '关联物品ID', `obtain_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '获取时间', PRIMARY KEY (`id`), UNIQUE KEY `user_item_unique` (`user_id`,`item_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
用户购买/获取物品时,需要往这张表插入对应关联记录。
修复后的render.php代码
<?php include "../../header.php"; // 先校验用户登录状态,未登录直接跳转 if (empty($myu->id)) { header("Location: /Customize/"); exit; } // 校验ID参数合法性 $id = $_GET['id'] ?? 0; if (!is_numeric($id) || $id <= 0) { header("Location: /Customize/"); exit; } // 预处理查询物品信息,避免SQL注入 $itemStmt = $handler->prepare("SELECT * FROM items WHERE id = ?"); $itemStmt->execute([$id]); $gI = $itemStmt->fetch(PDO::FETCH_OBJ); if (!$gI) { // 物品不存在直接跳转 header("Location: /Customize/"); exit; } // 核心校验:查询当前用户是否持有该物品 $ownStmt = $handler->prepare("SELECT id FROM user_items WHERE user_id = ? AND item_id = ? LIMIT 1"); $ownStmt->execute([$myu->id, $id]); $isOwn = $ownStmt->fetch(PDO::FETCH_ASSOC); if (!$isOwn) { // 用户未持有该物品,不执行装备操作直接跳转 header("Location: /Customize/"); exit; } // 校验通过才执行装备更新,同样用预处理避免注入 $updateStmt = $handler->prepare("UPDATE `users` SET `{$gI->type}` = ? WHERE `id` = ?"); $updateStmt->execute([$gI->wearable, $myu->id]); ?> <head><meta http-equiv="refresh" content="1; url=/Customize/"></head>
额外优化说明
- 原代码直接拼接SQL参数存在严重的SQL注入漏洞,修改后全部使用PDO预处理语句,彻底规避注入风险
- 增加了参数合法性、物品存在性、登录状态三层前置校验,避免非法参数导致的系统错误
- 核心持有校验逻辑会在所有更新操作前执行,只要用户没有对应物品的关联记录,就不会触发装备更新
内容的提问来源于stack exchange,提问作者CodeFlow
相关产品推荐
相关产品推荐

