PHP项目实现"人盯人防守成功率"统计
我理解你想在PHP项目里显示人盯人防守成功率,下面给你一套完整的实现思路和代码示例,不过我需要先说明:你没有提供具体的项目代码/数据库结构,所以我给的是通用方案,你可以按自己的表结构对照修改。

核心公式
人盯人防守成功率 = 成功防守次数 / 防守总次数 × 100%
关键是:什么算"成功防守"?常见定义:
- 对方持球人没有得分
- 对方没有形成有效传球/突破
- 对方投篮未命中且是你盯防的人
数据库设计(示例)
-- 防守事件记录表
CREATE TABLE defense_records (
id INT AUTO_INCREMENT PRIMARY KEY,
player_id INT NOT NULL COMMENT '防守球员ID',
opponent_id INT NOT NULL COMMENT '被盯防的对手ID',
match_id INT NOT NULL COMMENT '比赛ID',
defense_type ENUM('man_to_man','zone') DEFAULT 'man_to_man' COMMENT '防守类型',
is_success TINYINT(1) NOT NULL COMMENT '1=成功 0=失败',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
计算成功率的PHP代码
方式1:PDO查询单个球员
<?php
function getManToManSuccessRate(PDO $pdo, int $playerId, ?int $matchId = null): array
{
$sql = "SELECT
COUNT(*) AS total,
SUM(is_success) AS success
FROM defense_records
WHERE player_id = :player_id
AND defense_type = 'man_to_man'";
$params = [':player_id' => $playerId];
if ($matchId !== null) {
$sql .= " AND match_id = :match_id";
$params[':match_id'] = $matchId;
}
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$total = (int)($row['total'] ?? 0);
$success = (int)($row['success'] ?? 0);
$rate = $total > 0 ? round($success / $total * 100, 2) : 0.0;
return [
'total' => $total,
'success' => $success,
'rate' => $rate, // 百分比数值,如 78.57
];
}
// 使用示例
$pdo = new PDO('mysql:host=localhost;dbname=your_db;charset=utf8mb4', 'user', 'pass');
$result = getManToManSuccessRate($pdo, 10);
echo "人盯人防守成功率: {$result['rate']}% ({$result['success']}/{$result['total']})";
方式2:一次性查全队(排行榜)
function getTeamManToManRates(PDO $pdo, int $matchId): array
{
$sql = "SELECT
p.id,
p.name,
COUNT(d.id) AS total,
SUM(d.is_success) AS success,
ROUND(SUM(d.is_success) / COUNT(d.id) * 100, 2) AS rate
FROM defense_records d
JOIN players p ON p.id = d.player_id
WHERE d.match_id = :match_id
AND d.defense_type = 'man_to_man'
GROUP BY p.id, p.name
HAVING total > 0
ORDER BY rate DESC";
$stmt = $pdo->prepare($sql);
$stmt->execute([':match_id' => $matchId]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
在页面上显示(HTML模板)
<?php
$players = getTeamManToManRates($pdo, 1);
?>
<table border="1" cellpadding="8">
<thead>
<tr>
<th>球员</th>
<th>成功/总次数</th>
<th>人盯人防守成功率</th>
</tr>
</thead>
<tbody>
<?php foreach ($players as $p): ?>
<tr>
<td><?= htmlspecialchars($p['name']) ?></td>
<td><?= $p['success'] ?>/<?= $p['total'] ?></td>
<td>
<div style="background:#eee;width:120px;display:inline-block;vertical-align:middle;">
<div style="width:<?= $p['rate'] ?>%;background:#28a745;color:#fff;text-align:center;">
<?= $p['rate'] ?>%
</div>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
常见坑
| 问题 | 解决 |
|---|---|
| 除以0报错 | 先判断 total > 0 |
| 精度丢失 | 用 ROUND(...,2),或者SQL里用 SUM(x)/NULLIF(COUNT(*),0) |
| 只看单场还是赛季 | 加 match_id 过滤参数 |
| 数据量大变慢 | 给 (player_id, defense_type) 加联合索引 |
| 区分主客/不同战术 | defense_type 字段区分 |
需要你补充的信息
如果你想让代码直接能用在你的项目里,请告诉我:
- 你的数据库表结构(防守记录表字段有哪些?)
- "成功"的判定标准是什么?
- 是显示单个球员还是全队排行榜?
- 用的是 PDO / mysqli / 框架(ThinkPHP、Laravel),还是原生PHP?
把这些发给我,我可以直接帮你改成贴合项目的代码。