php项目统计禁区内射门次数对比?

wen PHP项目 3

本文目录导读:

php项目统计禁区内射门次数对比?

  1. 数据库设计
  2. PHP配置和数据库连接
  3. 射门统计类
  4. 页面展示
  5. 赛季统计数据
  6. 数据导入示例
  7. 使用说明

我来帮你创建一个PHP项目来统计禁区内射门次数对比,这个功能通常用于足球数据分析。

数据库设计

-- 球队表
CREATE TABLE teams (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    short_name VARCHAR(50)
);
-- 比赛表
CREATE TABLE matches (
    id INT PRIMARY KEY AUTO_INCREMENT,
    home_team_id INT,
    away_team_id INT,
    match_date DATE,
    competition VARCHAR(100),
    FOREIGN KEY (home_team_id) REFERENCES teams(id),
    FOREIGN KEY (away_team_id) REFERENCES teams(id)
);
-- 射门记录表
CREATE TABLE shots (
    id INT PRIMARY KEY AUTO_INCREMENT,
    match_id INT,
    team_id INT,
    player_id INT,
    shot_time INT,              -- 比赛时间(分钟)
    is_penalty_area BOOLEAN,    -- 是否禁区内
    is_goal BOOLEAN,            -- 是否进球
    shot_type VARCHAR(50),      -- 射门方式:右脚、左脚、头球等
    x_coordinate DECIMAL(4,2),  -- x坐标(用于技术分析)
    y_coordinate DECIMAL(4,2),  -- y坐标
    FOREIGN KEY (match_id) REFERENCES matches(id),
    FOREIGN KEY (team_id) REFERENCES teams(id)
);

PHP配置和数据库连接

// config.php - 数据库配置文件
<?php
define('DB_HOST', 'localhost');
define('DB_NAME', 'football_stats');
define('DB_USER', 'root');
define('DB_PASS', 'your_password');
function getConnection() {
    try {
        $dsn = 'mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8mb4';
        $pdo = new PDO($dsn, DB_USER, DB_PASS);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
        return $pdo;
    } catch (PDOException $e) {
        die('数据库连接失败: ' . $e->getMessage());
    }
}
?>

射门统计类

// ShotStatistics.php - 射门统计类
<?php
class ShotStatistics {
    private $db;
    public function __construct() {
        $this->db = getConnection();
    }
    // 获取比赛双方禁区内射门统计
    public function getPenaltyAreaShotsByMatch($matchId) {
        $sql = "SELECT 
                    t.id as team_id,
                    t.name as team_name,
                    COUNT(CASE WHEN s.is_penalty_area = 1 THEN 1 END) as area_shots,
                    COUNT(CASE WHEN s.is_penalty_area = 1 AND s.is_goal = 1 THEN 1 END) as area_goals,
                    COUNT(CASE WHEN s.is_penalty_area = 0 THEN 1 END) as outside_shots,
                    COUNT(CASE WHEN s.is_penalty_area = 0 AND s.is_goal = 1 THEN 1 END) as outside_goals,
                    COUNT(*) as total_shots
                FROM matches m
                INNER JOIN teams t ON t.id IN (m.home_team_id, m.away_team_id)
                LEFT JOIN shots s ON s.match_id = m.id AND s.team_id = t.id
                WHERE m.id = ?
                GROUP BY t.id, t.name";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$matchId]);
        return $stmt->fetchAll();
    }
    // 获取多场比赛的禁区内射门统计
    public function getSeasonPenaltyAreaStats($teamId = null, $startDate = null, $endDate = null) {
        $params = [];
        $sql = "SELECT 
                    t.id as team_id,
                    t.name as team_name,
                    COUNT(s.id) as total_shots,
                    SUM(s.is_penalty_area) as area_shots,
                    SUM(CASE WHEN s.is_penalty_area = 1 AND s.is_goal = 1 THEN 1 ELSE 0 END) as area_goals,
                    ROUND(SUM(s.is_penalty_area) / COUNT(s.id) * 100, 2) as area_shot_percentage,
                    ROUND(SUM(CASE WHEN s.is_penalty_area = 1 AND s.is_goal = 1 THEN 1 ELSE 0 END) / 
                          NULLIF(SUM(s.is_penalty_area), 0) * 100, 2) as area_conversion_rate
                FROM teams t
                LEFT JOIN shots s ON s.team_id = t.id
                LEFT JOIN matches m ON m.id = s.match_id
                WHERE 1=1";
        if ($teamId) {
            $sql .= " AND t.id = ?";
            $params[] = $teamId;
        }
        if ($startDate) {
            $sql .= " AND m.match_date >= ?";
            $params[] = $startDate;
        }
        if ($endDate) {
            $sql .= " AND m.match_date <= ?";
            $params[] = $endDate;
        }
        $sql .= " GROUP BY t.id, t.name ORDER BY area_shots DESC";
        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetchAll();
    }
    // 获取球员禁区内射门统计
    public function getPlayerAreaShots($playerId) {
        $sql = "SELECT 
                    p.name as player_name,
                    COUNT(*) as total_shots,
                    SUM(CASE WHEN s.is_penalty_area = 1 THEN 1 ELSE 0 END) as area_shots,
                    SUM(CASE WHEN s.is_penalty_area = 1 AND s.is_goal = 1 THEN 1 ELSE 0 END) as area_goals
                FROM players p
                LEFT JOIN shots s ON s.player_id = p.id
                WHERE p.id = ?
                GROUP BY p.name";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$playerId]);
        return $stmt->fetch();
    }
    // 获取每场比赛禁区内射门时间分布
    public function getShotTimeDistribution($matchId) {
        $sql = "SELECT 
                    CASE 
                        WHEN shot_time BETWEEN 0 AND 15 THEN '0-15分钟'
                        WHEN shot_time BETWEEN 16 AND 30 THEN '16-30分钟'
                        WHEN shot_time BETWEEN 31 AND 45 THEN '31-45分钟'
                        WHEN shot_time BETWEEN 46 AND 60 THEN '46-60分钟'
                        WHEN shot_time BETWEEN 61 AND 75 THEN '61-75分钟'
                        ELSE '76-90分钟'
                    END as time_period,
                    COUNT(CASE WHEN is_penalty_area = 1 THEN 1 END) as area_shots,
                    COUNT(CASE WHEN is_penalty_area = 0 THEN 1 END) as outside_shots,
                    COUNT(*) as total_shots
                FROM shots
                WHERE match_id = ?
                GROUP BY time_period
                ORDER BY shot_time";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$matchId]);
        return $stmt->fetchAll();
    }
}
?>

页面展示

// compare_shots.php - 禁区内射门对比页面
<?php
require_once 'config.php';
require_once 'ShotStatistics.php';
$stats = new ShotStatistics();
// 获取比赛列表(用于选择)
$db = getConnection();
$matches = $db->query("SELECT m.id, 
                       home.name as home_team, 
                       away.name as away_team, 
                       m.match_date
                       FROM matches m
                       JOIN teams home ON home.id = m.home_team_id
                       JOIN teams away ON away.id = m.away_team_id
                       ORDER BY m.match_date DESC LIMIT 10")->fetchAll();
$selectedMatch = isset($_GET['match_id']) ? $_GET['match_id'] : (isset($matches[0]) ? $matches[0]['id'] : null);
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">禁区内射门统计对比</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <style>
        .container { max-width: 1200px; margin-top: 30px; }
        .card { margin-bottom: 20px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
        .stat-card { border-radius: 8px; }
        .area-highlight { background-color: #28a745; color: white; }
        .progress { height: 30px; }
    </style>
</head>
<body>
<div class="container">
    <h1 class="mb-4">⚽ 禁区内射门统计对比</h1>
    <!-- 比赛选择 -->
    <div class="card p-3 mb-4">
        <form method="GET" class="row g-3">
            <div class="col-md-6">
                <label for="match_id" class="form-label">选择比赛</label>
                <select name="match_id" id="match_id" class="form-select" onchange="this.form.submit()">
                    <?php foreach ($matches as $match): ?>
                        <option value="<?= $match['id'] ?>" <?= $selectedMatch == $match['id'] ? 'selected' : '' ?>>
                            <?= $match['home_team'] ?> vs <?= $match['away_team'] ?> (<?= date('Y-m-d', strtotime($match['match_date'])) ?>)
                        </option>
                    <?php endforeach; ?>
                </select>
            </div>
        </form>
    </div>
    <?php if ($selectedMatch): ?>
        <?php $matchStats = $stats->getPenaltyAreaShotsByMatch($selectedMatch); ?>
        <!-- 射门对比图表 -->
        <div class="card p-4">
            <h4 class="mb-3">禁区内射门对比</h4>
            <div class="row">
                <div class="col-md-8">
                    <canvas id="shotChart"></canvas>
                </div>
                <div class="col-md-4">
                    <?php foreach ($matchStats as $team): ?>
                        <div class="mb-3 p-3 border rounded">
                            <h5><?= $team['team_name'] ?></h5>
                            <div class="mb-2">禁区内射门: <strong><?= $team['area_shots'] ?? 0 ?></strong> 次</div>
                            <div class="mb-2">禁区外射门: <strong><?= $team['outside_shots'] ?? 0 ?></strong> 次</div>
                            <div class="mb-2">禁区内进球: <strong class="text-success"><?= $team['area_goals'] ?? 0 ?></strong> 个</div>
                            <div class="progress mb-2">
                                <div class="progress-bar bg-success" style="width: <?= $team['total_shots'] > 0 ? ($team['area_shots'] / $team['total_shots'] * 100) : 0 ?>%">
                                    <?= $team['total_shots'] > 0 ? round($team['area_shots'] / $team['total_shots'] * 100) : 0 ?>%
                                </div>
                            </div>
                            <small class="text-muted">禁区内射门占比</small>
                        </div>
                    <?php endforeach; ?>
                </div>
            </div>
        </div>
        <!-- 射门时间分布 -->
        <div class="card p-4 mt-4">
            <h4>射门时间分布</h4>
            <canvas id="timeChart" width="400" height="200"></canvas>
        </div>
        <!-- 统计数据表 -->
        <div class="card p-4 mt-4">
            <h4>详细统计</h4>
            <table class="table table-striped">
                <thead>
                    <tr>
                        <th>球队</th>
                        <th>总射门</th>
                        <th>禁区内射门</th>
                        <th>禁区外射门</th>
                        <th>禁区内进球</th>
                        <th>禁区射门转化率</th>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach ($matchStats as $team): ?>
                    <tr>
                        <td><?= $team['team_name'] ?></td>
                        <td><?= $team['total_shots'] ?></td>
                        <td class="text-success"><?= $team['area_shots'] ?? 0 ?></td>
                        <td><?= $team['outside_shots'] ?? 0 ?></td>
                        <td><?= $team['area_goals'] ?? 0 ?></td>
                        <td>
                            <?= $team['area_shots'] > 0 ? number_format($team['area_goals'] / $team['area_shots'] * 100, 2) : 0 ?>%
                        </td>
                    </tr>
                    <?php endforeach; ?>
                </tbody>
            </table>
        </div>
        <script>
            // 射门对比图表
            const matchStats = <?= json_encode($matchStats) ?>;
            const ctx1 = document.getElementById('shotChart').getContext('2d');
            new Chart(ctx1, {
                type: 'bar',
                data: {
                    labels: matchStats.map(t => t.team_name),
                    datasets: [
                        {
                            label: '禁区内射门',
                            data: matchStats.map(t => t.area_shots || 0),
                            backgroundColor: 'rgba(40, 167, 69, 0.7)',
                            borderColor: 'rgba(40, 167, 69, 1)',
                            borderWidth: 1
                        },
                        {
                            label: '禁区外射门',
                            data: matchStats.map(t => t.outside_shots || 0),
                            backgroundColor: 'rgba(255, 193, 7, 0.7)',
                            borderColor: 'rgba(255, 193, 7, 1)',
                            borderWidth: 1
                        }
                    ]
                },
                options: {
                    scales: {
                        y: {
                            beginAtZero: true,
                            title: {
                                display: true,
                                text: '射门次数'
                            }
                        }
                    },
                    plugins: {
                        title: {
                            display: true,
                            text: '球队射门分布对比'
                        }
                    }
                }
            });
        </script>
    <?php endif; ?>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

赛季统计数据

// season_stats.php - 赛季禁区内射门统计
<?php
require_once 'config.php';
require_once 'ShotStatistics.php';
$stats = new ShotStatistics();
$seasonStats = $stats->getSeasonPenaltyAreaStats(null, '2024-01-01', '2024-12-31');
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">赛季禁区内射门统计</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-4">
    <h2>2024赛季禁区内射门统计</h2>
    <div class="card p-4">
        <table class="table table-hover">
            <thead>
                <tr>
                    <th>排名</th>
                    <th>球队</th>
                    <th>总射门</th>
                    <th>禁区内射门</th>
                    <th>禁区内进球</th>
                    <th>禁区射门占比</th>
                    <th>禁区进球转化率</th>
                </tr>
            </thead>
            <tbody>
                <?php $rank = 1; ?>
                <?php foreach ($seasonStats as $stat): ?>
                <tr>
                    <td><?= $rank++ ?></td>
                    <td><?= $stat['team_name'] ?></td>
                    <td><?= $stat['total_shots'] ?></td>
                    <td><?= $stat['area_shots'] ?></td>
                    <td><?= $stat['area_goals'] ?></td>
                    <td><?= $stat['area_shot_percentage'] ?>%</td>
                    <td><?= $stat['area_conversion_rate'] ?>%</td>
                </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
    </div>
</div>
</body>
</html>

数据导入示例

// import_shots_data.php - 数据导入示例
<?php
require_once 'ShotStatistics.php';
function importShotData($matchId, $shots) {
    $db = getConnection();
    $insertSql = "INSERT INTO shots (match_id, team_id, player_id, shot_time, is_penalty_area, is_goal, shot_type, x_coordinate, y_coordinate)
                  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
    $stmt = $db->prepare($insertSql);
    foreach ($shots as $shot) {
        $stmt->execute([
            $matchId,
            $shot['team_id'],
            $shot['player_id'],
            $shot['shot_time'],
            $shot['is_penalty_area'],
            $shot['is_goal'],
            $shot['shot_type'],
            $shot['x_coordinate'],
            $shot['y_coordinate']
        ]);
    }
    echo "成功导入 " . count($shots) . " 条射门数据";
}
?>

使用说明

  1. 配置数据库: 执行提供的SQL语句创建表结构
  2. 设置连接: 修改config.php中的数据库连接信息
  3. 导入数据: 通过管理后台录入或批量导入射门数据
  4. 访问页面:
    • 运行compare_shots.php查看单场比赛对比
    • 运行season_stats.php查看赛季统计数据

这个系统的特点:

  • 支持多场比赛、多球队对比
  • 提供可视化图表展示
  • 可扩展性强,可以添加更多统计维度(如射门方向、射门方式等)
  • 支持时间段筛选和历史数据对比

你可以根据实际需求调整统计维度和展示方式,需要我添加其他功能吗?

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