PHP项目中"协防补位成功次数"的实现分析
由于没有看到你的具体代码,我基于常见 PHP 游戏/社交项目场景给你分析这个功能通常怎么实现。

数据库设计
通常协防补位相关数据会有专门的表或字段:
-- 方式1:单独的协防记录表 CREATE TABLE `defense_assist_log` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `user_id` int NOT NULL COMMENT '协防者ID', `target_id` int NOT NULL COMMENT '被协防者ID', `battle_id` varchar(64) NOT NULL COMMENT '战斗/事件ID', `result` tinyint NOT NULL DEFAULT 0 COMMENT '0失败 1成功', `created_at` datetime NOT NULL, PRIMARY KEY (`id`), KEY `idx_user_result` (`user_id`, `result`) ); -- 方式2:用户统计表冗余字段 ALTER TABLE `user_stat` ADD `defense_assist_success_count` int NOT NULL DEFAULT 0;
计数的典型 PHP 实现
实时统计(查日志表)
// 统计某用户协防补位成功次数
public function getAssistSuccessCount(int $userId): int
{
$sql = "SELECT COUNT(*) FROM defense_assist_log
WHERE user_id = ? AND result = 1";
return (int)$this->db->fetchOne($sql, [$userId]);
}
增量累加(推荐,性能好)
// 协防结算时调用
public function onDefenseAssistSettled(int $userId, int $targetId, bool $isSuccess)
{
$this->db->beginTransaction();
try {
// 1. 写日志
$this->db->insert('defense_assist_log', [
'user_id' => $userId,
'target_id' => $targetId,
'result' => $isSuccess ? 1 : 0,
'created_at' => date('Y-m-d H:i:s'),
]);
// 2. 成功才累加统计
if ($isSuccess) {
$this->db->exec(
"UPDATE user_stat SET defense_assist_success_count = defense_assist_success_count + 1
WHERE user_id = ?", [$userId]
);
}
$this->db->commit();
} catch (\Throwable $e) {
$this->db->rollBack();
throw $e;
}
}
读取
public function getUserAssistStat(int $userId): array
{
return $this->db->fetchRow(
"SELECT defense_assist_success_count FROM user_stat WHERE user_id = ?",
[$userId]
) ?? ['defense_assist_success_count' => 0];
}
常见坑点
| 问题 | 说明 |
|---|---|
| 重复结算 | 同一场战斗重复回调会导致重复计数,要用 battle_id 唯一索引 + INSERT IGNORE |
| 事务缺失 | 写日志和累加必须同一事务 |
| 并发更新 | 用 SET x = x + 1 而非先读后写 |
| 判定口径 | "成功"的定义要明确(守住?补位到场?击杀?) |
| 缓存不一致 | 有 Redis 缓存时要同步失效或更新 |
需要你补充的信息
为了给你精准的答案,请提供:
- 相关表结构(协防日志表名、字段)
- "成功"的判定逻辑在哪段代码(结算函数)
- 你想解决的具体问题:
- 统计总数不准?
- 重复计数?
- 不知道怎么查?
- 性能问题?
贴出相关代码或表结构,我可以直接帮你定位并给出修复方案。