这个php项目显示人盯人防守成功率?

wen PHP项目 1

PHP 项目实现"人盯人防守成功率"统计

你需要明确一下需求,我先给你一个通用的实现方案关键代码示例,因为"人盯人防守成功率"在篮球/足球统计中定义不同,我按篮球场景来写。

这个php项目显示人盯人防守成功率?


先明确业务定义

"人盯人防守成功率"通常指:

成功率 = 成功防守回合数 / 总盯人防守回合数 × 100%

什么算"成功"? 常见判定:

  • 对手未得分
  • 对手失误
  • 对手投篮不中
  • 造成进攻犯规

什么算"失败"?

  • 对手得分
  • 被突破导致失分
  • 防守犯规送罚球

数据库设计

-- 球员表
CREATE TABLE players (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50),
    team VARCHAR(50)
);
-- 防守回合记录表
CREATE TABLE defense_records (
    id INT PRIMARY KEY AUTO_INCREMENT,
    player_id INT,                      -- 防守人
    opponent_id INT,                    -- 被防守人
    match_id INT,                       -- 比赛ID
    defense_type ENUM('man','zone') DEFAULT 'man',  -- 防守类型
    result ENUM('success','fail') NOT NULL,         -- 结果
    reason VARCHAR(50),                 -- 原因: steal/miss/score/foul...
    quarter TINYINT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (player_id) REFERENCES players(id)
);

核心 PHP 代码

配置 & 数据库连接 db.php

<?php
$pdo = new PDO('mysql:host=localhost;dbname=basketball;charset=utf8mb4',
               'root', 'password', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);

计算成功率的模型 DefenseStats.php

<?php
require 'db.php';
class DefenseStats
{
    private PDO $pdo;
    public function __construct(PDO $pdo) {
        $this->pdo = $pdo;
    }
    /**
     * 统计某个球员的人盯人防守成功率
     */
    public function manToManRate(int $playerId, ?int $matchId = null): array
    {
        $sql = "SELECT 
                    COUNT(*) AS total,
                    SUM(result = 'success') AS success,
                    SUM(result = 'fail')    AS fail
                FROM defense_records
                WHERE player_id = :pid
                  AND defense_type = 'man'";
        $params = ['pid' => $playerId];
        if ($matchId !== null) {
            $sql .= " AND match_id = :mid";
            $params['mid'] = $matchId;
        }
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute($params);
        $row = $stmt->fetch();
        $total   = (int)$row['total'];
        $success = (int)$row['success'];
        $rate    = $total > 0 ? round($success / $total * 100, 2) : 0.0;
        return [
            'player_id' => $playerId,
            'total'     => $total,
            'success'   => $success,
            'fail'      => (int)$row['fail'],
            'rate'      => $rate,   // 百分比,例:73.21
        ];
    }
    /**
     * 全队排行(按成功率降序)
     */
    public function teamRanking(int $matchId): array
    {
        $sql = "SELECT p.id, p.name,
                       COUNT(*) AS total,
                       SUM(d.result='success') AS success,
                       ROUND(SUM(d.result='success') / COUNT(*) * 100, 2) AS rate
                FROM defense_records d
                JOIN players p ON p.id = d.player_id
                WHERE d.defense_type = 'man' AND d.match_id = :mid
                GROUP BY p.id, p.name
                HAVING total >= 5
                ORDER BY rate DESC";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute(['mid' => $matchId]);
        return $stmt->fetchAll();
    }
}

调用示例 index.php

<?php
require 'DefenseStats.php';
$stats = new DefenseStats($pdo);
// 单个球员本赛季人盯人成功率
$result = $stats->manToManRate(playerId: 7);
printf("球员%d:%d/%d,成功率 %.2f%%\n",
    $result['player_id'],
    $result['success'],
    $result['total'],
    $result['rate']
);
// 本场比赛全队排行
foreach ($stats->teamRanking(matchId: 101) as $r) {
    printf("%-10s  %3d/%3d  %.2f%%\n",
        $r['name'], $r['success'], $r['total'], $r['rate']);
}

输出示例:

球员7:11/15,成功率 73.33%
张三    11/15   73.33%
李四     9/12   75.00%
王五     4/10   40.00%

进阶:加入"加权成功率"

不同防守结果价值不同,可以加权:

// 权重:抢断 1.2,逼迫失误 1.1,投篮不中 1.0,得分 -1.0,犯规 -0.8
$weights = [
    'steal'  => 1.2,
    'turnover' => 1.1,
    'miss'   => 1.0,
    'score'  => -1.0,
    'foul'   => -0.8,
];
$sql = "SELECT SUM(CASE reason
                    WHEN 'steal' THEN 1.2
                    WHEN 'turnover' THEN 1.1
                    WHEN 'miss' THEN 1.0
                    WHEN 'score' THEN -1.0
                    WHEN 'foul' THEN -0.8
                   END) AS score,
               COUNT(*) AS total
        FROM defense_records
        WHERE player_id = ? AND defense_type='man'";

常见坑提醒

问题 说明
除零错误 total=0 时必须返回 0,不能直接除
样本太小 出场<5次不建议排名(用 HAVING total >= 5
换防归属 挡拆换防后,谁算防守人?建议记录表存"实际防守人"
时间维度 是"本场"还是"赛季"?一定要在 SQL 里区分 match_id
快攻/协防 是否算人盯人?最好和录像剪辑规则对齐

你能补充下具体场景吗?

  1. 是篮球还是足球?
  2. 有没有现成的数据表结构?
  3. 是要网页展示(配图表)还是接口返回 JSON?

告诉我这些,我可以给你贴合你项目的完整代码。

抱歉,评论功能暂时关闭!