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

wen PHP项目 1

本文目录导读:

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

  1. 项目结构
  2. 数据库结构 (database.sql)
  3. 配置文件 (config.php)
  4. 主页面 (index.php)
  5. 添加数据处理 (add_defense.php)
  6. 样式文件 (style.css)
  7. JavaScript (js/script.js)
  8. 使用方法

我可以帮你设计一个显示人盯人防守成功率的PHP项目,让我创建一个完整的示例:

项目结构

basketball-defense/
├── index.php          # 主页面
├── config.php         # 数据库配置
├── style.css          # 样式文件
├── js/script.js       # JavaScript文件
└── database.sql       # 数据库结构

数据库结构 (database.sql)

CREATE DATABASE IF NOT EXISTS basketball_stats;
USE basketball_stats;
-- 球员表
CREATE TABLE players (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    position VARCHAR(20),
    team VARCHAR(50),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 防守数据表
CREATE TABLE defense_stats (
    id INT PRIMARY KEY AUTO_INCREMENT,
    player_id INT,
    match_date DATE,
    opponent_player VARCHAR(50),
    defensive_attempts INT DEFAULT 0,  -- 防守次数
    successful_defenses INT DEFAULT 0,  -- 成功防守次数
    blocks INT DEFAULT 0,             -- 盖帽数
    steals INT DEFAULT 0,             -- 抢断数
    fouls INT DEFAULT 0,              -- 犯规数
    FOREIGN KEY (player_id) REFERENCES players(id)
);
-- 示例数据
INSERT INTO players (name, position, team) VALUES
('张三', '后卫', '雷霆队'),
('李四', '前锋', '雷霆队'),
('王五', '中锋', '雷霆队'),
('赵六', '后卫', '勇士队');
INSERT INTO defense_stats (player_id, match_date, opponent_player, defensive_attempts, successful_defenses, blocks, steals, fouls) VALUES
(1, '2024-01-15', '库里', 12, 8, 1, 2, 3),
(1, '2024-01-20', '詹姆斯', 15, 10, 2, 1, 2),
(2, '2024-01-15', '杜兰特', 10, 6, 1, 1, 4),
(2, '2024-01-20', '字母哥', 14, 9, 3, 0, 2),
(3, '2024-01-15', '约基奇', 18, 12, 4, 1, 3),
(3, '2024-01-20', '恩比德', 16, 11, 3, 0, 2);

配置文件 (config.php)

<?php
session_start();
// 数据库配置
define('DB_HOST', 'localhost');
define('DB_USER', 'root');
define('DB_PASS', '');
define('DB_NAME', 'basketball_stats');
// 连接数据库
function dbConnect() {
    try {
        $conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
        if ($conn->connect_error) {
            throw new Exception("连接失败: " . $conn->connect_error);
        }
        $conn->set_charset("utf8mb4");
        return $conn;
    } catch (Exception $e) {
        die("数据库连接错误: " . $e->getMessage());
    }
}
// 计算防守成功率
function calculateDefenseRate($successful, $attempts) {
    if ($attempts <= 0) return 0;
    return round(($successful / $attempts) * 100, 2);
}
// 获取球员防守统计数据
function getPlayerDefenseStats($playerId = null) {
    $conn = dbConnect();
    $where = $playerId ? "WHERE p.id = $playerId" : "";
    $sql = "SELECT 
                p.id,
                p.name,
                p.position,
                p.team,
                COUNT(ds.id) as matches_played,
                SUM(ds.defensive_attempts) as total_attempts,
                SUM(ds.successful_defenses) as total_successful,
                SUM(ds.blocks) as total_blocks,
                SUM(ds.steals) as total_steals,
                SUM(ds.fouls) as total_fouls,
                AVG(ds.defensive_attempts) as avg_attempts_per_match,
                AVG(ds.successful_defenses) as avg_successful_per_match
            FROM players p
            LEFT JOIN defense_stats ds ON p.id = ds.player_id
            $where
            GROUP BY p.id
            ORDER BY (SUM(ds.successful_defenses)/NULLIF(SUM(ds.defensive_attempts),0)) DESC";
    $result = $conn->query($sql);
    $stats = [];
    if ($result) {
        while ($row = $result->fetch_assoc()) {
            // 计算防守成功率
            $row['defense_rate'] = calculateDefenseRate(
                $row['total_successful'], 
                $row['total_attempts']
            );
            // 计算场均防守效率评分
            $row['defense_rating'] = calculateDefenseRating($row);
            $stats[] = $row;
        }
    }
    $conn->close();
    return $stats;
}
// 计算防守效率评分 (综合评分)
function calculateDefenseRating($stats) {
    $rate = $stats['defense_rate'];
    $blocks_effect = ($stats['total_blocks'] ?? 0) * 2;
    $steals_effect = ($stats['total_steals'] ?? 0) * 1.5;
    $fouls_penalty = ($stats['total_fouls'] ?? 0) * -0.5;
    return round($rate + $blocks_effect + $steals_effect + $fouls_penalty, 2);
}
?>

主页面 (index.php)

<?php
require_once 'config.php';
// 获取筛选参数
$selectedPlayer = isset($_GET['player_id']) ? $_GET['player_id'] : null;
$dateFrom = isset($_GET['date_from']) ? $_GET['date_from'] : '';
$dateTo = isset($_GET['date_to']) ? $_GET['date_to'] : '';
// 获取统计数据
$stats = getPlayerDefenseStats($selectedPlayer);
// 获取所有球员用于筛选
$conn = dbConnect();
$players = $conn->query("SELECT id, name FROM players ORDER BY name");
$conn->close();
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">人盯人防守成功率分析系统</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <header>
            <h1>🏀 人盯人防守成功率分析</h1>
            <p class="subtitle">实时监控球队防守表现</p>
        </header>
        <nav class="filter-section">
            <form method="GET" action="index.php" class="filter-form">
                <div class="filter-group">
                    <label>球员筛选:</label>
                    <select name="player_id">
                        <option value="">全部球员</option>
                        <?php while($player = $players->fetch_assoc()): ?>
                            <option value="<?php echo $player['id']; ?>" 
                                <?php echo $selectedPlayer == $player['id'] ? 'selected' : ''; ?>>
                                <?php echo htmlspecialchars($player['name']); ?>
                            </option>
                        <?php endwhile; ?>
                    </select>
                </div>
                <div class="filter-group">
                    <label>开始日期:</label>
                    <input type="date" name="date_from" value="<?php echo $dateFrom; ?>">
                </div>
                <div class="filter-group">
                    <label>结束日期:</label>
                    <input type="date" name="date_to" value="<?php echo $dateTo; ?>">
                </div>
                <button type="submit" class="btn-filter">筛选数据</button>
                <a href="index.php" class="btn-reset">重置</a>
            </form>
        </nav>
        <!-- 数据总览卡片 -->
        <div class="summary-cards">
            <?php
            $avgRate = count($stats) > 0 ? array_sum(array_column($stats, 'defense_rate')) / count($stats) : 0;
            $totalBlocks = array_sum(array_column($stats, 'total_blocks'));
            $totalSteals = array_sum(array_column($stats, 'total_steals'));
            ?>
            <div class="card">
                <div class="card-icon">📊</div>
                <div class="card-value"><?php echo round($avgRate, 1); ?>%</div>
                <div class="card-label">平均防守成功率</div>
            </div>
            <div class="card">
                <div class="card-icon">🛡️</div>
                <div class="card-value"><?php echo $totalBlocks; ?></div>
                <div class="card-label">总盖帽数</div>
            </div>
            <div class="card">
                <div class="card-icon">✋</div>
                <div class="card-value"><?php echo $totalSteals; ?></div>
                <div class="card-label">总抢断数</div>
            </div>
            <div class="card">
                <div class="card-icon">🎯</div>
                <div class="card-value"><?php echo count($stats); ?></div>
                <div class="card-label">球员数量</div>
            </div>
        </div>
        <!-- 主要数据表格 -->
        <div class="table-container">
            <h2>球员防守统计排名</h2>
            <table>
                <thead>
                    <tr>
                        <th>排名</th>
                        <th>球员</th>
                        <th>位置</th>
                        <th>球队</th>
                        <th>场次</th>
                        <th>防守次数</th>
                        <th>成功防守</th>
                        <th>成功率</th>
                        <th>盖帽</th>
                        <th>抢断</th>
                        <th>犯规</th>
                        <th>防守评分</th>
                        <th>表现</th>
                    </tr>
                </thead>
                <tbody>
                    <?php $rank = 1; foreach($stats as $stat): ?>
                    <tr>
                        <td>
                            <span class="rank <?php echo $rank <= 3 ? 'top-3' : ''; ?>">
                                <?php echo $rank; ?>
                            </span>
                        </td>
                        <td><?php echo htmlspecialchars($stat['name']); ?></td>
                        <td><?php echo htmlspecialchars($stat['position']); ?></td>
                        <td><?php echo htmlspecialchars($stat['team']); ?></td>
                        <td><?php echo $stat['matches_played']; ?></td>
                        <td><?php echo $stat['total_attempts']; ?></td>
                        <td><?php echo $stat['total_successful']; ?></td>
                        <td class="rate-cell">
                            <div class="progress-wrapper">
                                <div class="progress-bar" style="width: <?php echo $stat['defense_rate']; ?>%;"></div>
                                <span><?php echo $stat['defense_rate']; ?>%</span>
                            </div>
                        </td>
                        <td><?php echo $stat['total_blocks']; ?></td>
                        <td><?php echo $stat['total_steals']; ?></td>
                        <td><?php echo $stat['total_fouls']; ?></td>
                        <td class="rating-cell">
                            <?php echo $stat['defense_rating']; ?>
                            <?php 
                            $ratingClass = $stat['defense_rating'] > 70 ? 'excellent' : ($stat['defense_rating'] > 50 ? 'good' : 'needs-improvement');
                            ?>
                            <div class="rating-dot <?php echo $ratingClass; ?>"></div>
                        </td>
                        <td>
                            <?php
                            $performance = $stat['defense_rating'] > 70 ? '🎖️' : ($stat['defense_rating'] > 50 ? '💪' : '📝');
                            echo $performance;
                            ?>
                        </td>
                    </tr>
                    <?php $rank++; endforeach; ?>
                </tbody>
            </table>
        </div>
        <!-- 添加新数据的表单 -->
        <div class="data-entry-section">
            <h2>添加防守数据</h2>
            <form method="POST" action="add_defense.php" class="data-form">
                <div class="form-grid">
                    <div class="form-group">
                        <label>球员</label>
                        <select name="player_id" required>
                            <option value="">选择球员...</option>
                            <?php
                            $conn = dbConnect();
                            $playersList = $conn->query("SELECT id, name FROM players ORDER BY name");
                            while($p = $playersList->fetch_assoc()):
                            ?>
                                <option value="<?php echo $p['id']; ?>"><?php echo $p['name']; ?></option>
                            <?php endwhile; ?>
                        </select>
                    </div>
                    <div class="form-group">
                        <label>对手球员</label>
                        <input type="text" name="opponent_player" required>
                    </div>
                    <div class="form-group">
                        <label>比赛日期</label>
                        <input type="date" name="match_date" required>
                    </div>
                    <div class="form-group">
                        <label>防守次数</label>
                        <input type="number" name="defensive_attempts" min="0" required>
                    </div>
                    <div class="form-group">
                        <label>成功防守次数</label>
                        <input type="number" name="successful_defenses" min="0" required>
                    </div>
                    <div class="form-group">
                        <label>盖帽数</label>
                        <input type="number" name="blocks" min="0" value="0">
                    </div>
                    <div class="form-group">
                        <label>抢断数</label>
                        <input type="number" name="steals" min="0" value="0">
                    </div>
                    <div class="form-group">
                        <label>犯规数</label>
                        <input type="number" name="fouls" min="0" value="0">
                    </div>
                </div>
                <button type="submit" class="btn-submit">提交数据</button>
            </form>
        </div>
    </div>
    <script src="js/script.js"></script>
</body>
</html>

添加数据处理 (add_defense.php)

<?php
require_once 'config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $player_id = $_POST['player_id'];
    $opponent_player = $_POST['opponent_player'];
    $match_date = $_POST['match_date'];
    $defensive_attempts = $_POST['defensive_attempts'];
    $successful_defenses = $_POST['successful_defenses'];
    $blocks = $_POST['blocks'];
    $steals = $_POST['steals'];
    $fouls = $_POST['fouls'];
    // 验证数据
    if ($successful_defenses > $defensive_attempts) {
        header('Location: index.php?error=successful_defenses_exceed');
        exit;
    }
    $conn = dbConnect();
    $sql = "INSERT INTO defense_stats 
            (player_id, opponent_player, match_date, defensive_attempts, successful_defenses, blocks, steals, fouls) 
            VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("issiiiii", $player_id, $opponent_player, $match_date, $defensive_attempts, $successful_defenses, $blocks, $steals, $fouls);
    if ($stmt->execute()) {
        header('Location: index.php?success=1');
    } else {
        header('Location: index.php?error=db_error');
    }
    $stmt->close();
    $conn->close();
}
?>

样式文件 (style.css)

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    min-height: 100vh;
    padding: 20px;
}
.container {
    max-width: 1400px;
    margin: 0 auto;
    background: #fff;
    border-radius: 20px;
    box-shadow: 0 20px 40px rgba(0,0,0,0.1);
    overflow: hidden;
}
header {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    padding: 30px;
    text-align: center;
}
header h1 {
    font-size: 2.5em;
    margin-bottom: 10px;
}
{
    opacity: 0.9;
    font-size: 1.2em;
}
/* 筛选区域 */
.filter-section {
    background: #f8f9fa;
    padding: 20px;
    border-bottom: 1px solid #dee2e6;
}
.filter-form {
    display: flex;
    flex-wrap: wrap;
    gap: 15px;
    align-items: flex-end;
}
.filter-group {
    display: flex;
    flex-direction: column;
    gap: 5px;
}
.filter-group label {
    font-weight: bold;
    color: #495057;
    font-size: 14px;
}
.filter-group select,
.filter-group input {
    padding: 8px 12px;
    border: 1px solid #ced4da;
    border-radius: 5px;
    font-size: 14px;
}
/* 统计卡片 */
.summary-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 20px;
    padding: 30px;
    background: #f8f9fa;
}
.card {
    background: white;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 4px 6px rgba(0,0,0,0.1);
    text-align: center;
    transition: transform 0.3s;
}
.card:hover {
    transform: translateY(-5px);
    box-shadow: 0 8px 12px rgba(0,0,0,0.15);
}
.card-icon {
    font-size: 2.5em;
    margin-bottom: 10px;
}
.card-value {
    font-size: 2em;
    font-weight: bold;
    color: #667eea;
}
.card-label {
    color: #6c757d;
    font-size: 14px;
    margin-top: 5px;
}
/* 表格样式 */
.table-container {
    padding: 30px;
}
.table-container h2 {
    margin-bottom: 20px;
    color: #343a40;
}
table {
    width: 100%;
    border-collapse: collapse;
    background: white;
}
th {
    background: #667eea;
    color: white;
    padding: 12px;
    text-align: left;
    font-size: 14px;
    white-space: nowrap;
}
td {
    padding: 10px;
    border-bottom: 1px solid #dee2e6;
    font-size: 14px;
}
tr:hover {
    background-color: #f8f9fa;
}
.rank {
    display: inline-block;
    width: 30px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    border-radius: 50%;
    background: #e9ecef;
    color: #343a40;
    font-weight: bold;
}
.rank.top-3 {
    background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
    color: white;
}
/* 进度条 */
.progress-wrapper {
    width: 150px;
    height: 20px;
    background: #e9ecef;
    border-radius: 10px;
    position: relative;
    overflow: hidden;
}
.progress-bar {
    height: 100%;
    background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
    border-radius: 10px;
    transition: width 0.3s;
}
.progress-wrapper span {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 12px;
    font-weight: bold;
    color: white;
    text-shadow: 1px 1px 2px rgba(0,0,0,0.3);
}
/* 评分 */
.rating-cell {
    position: relative;
}
.rating-dot {
    position: absolute;
    top: 5px;
    right: 5px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
}
.rating-dot.excellent {
    background: #28a745;
    animation: pulse 1s infinite;
}
.rating-dot.good {
    background: #ffc107;
}
.rating-dot.needs-improvement {
    background: #dc3545;
}
@keyframes pulse {
    0% { transform: scale(1); }
    50% { transform: scale(1.3); }
    100% { transform: scale(1); }
}
/* 添加数据表单 */
.data-entry-section {
    padding: 30px;
    background: #f8f9fa;
    border-top: 1px solid #dee2e6;
}
.data-entry-section h2 {
    margin-bottom: 20px;
    color: #343a40;
}
.data-form {
    background: white;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 20px;
    margin-bottom: 20px;
}
.form-group {
    display: flex;
    flex-direction: column;
    gap: 5px;
}
.form-group label {
    font-weight: bold;
    color: #495057;
}
.form-group input,
.form-group select {
    padding: 8px 12px;
    border: 1px solid #ced4da;
    border-radius: 5px;
}
.btn-submit,
.btn-filter {
    background: #667eea;
    color: white;
    padding: 12px 24px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    font-size: 16px;
    font-weight: bold;
    transition: background 0.3s;
}
.btn-submit:hover,
.btn-filter:hover {
    background: #5a67d8;
}
.btn-reset {
    background: #6c757d;
    color: white;
    padding: 12px 24px;
    border: none;
    border-radius: 5px;
    text-decoration: none;
}
/* 响应式设计 */
@media (max-width: 768px) {
    .filter-form {
        flex-direction: column;
    }
    .summary-cards {
        grid-template-columns: repeat(2, 1fr);
        padding: 15px;
    }
    .table-container {
        padding: 15px;
        overflow-x: auto;
    }
    .data-entry-section {
        padding: 15px;
    }
    .form-grid {
        grid-template-columns: 1fr;
    }
}

JavaScript (js/script.js)

// 数据过滤和交互逻辑
document.addEventListener('DOMContentLoaded', function() {
    // 添加表单验证
    const dataForm = document.querySelector('.data-form');
    if (dataForm) {
        dataForm.addEventListener('submit', function(e) {
            const attempts = parseInt(document.querySelector('input[name="defensive_attempts"]').value);
            const successful = parseInt(document.querySelector('input[name="successful_defenses"]').value);
            if (successful > attempts) {
                e.preventDefault();
                alert('错误:成功防守次数不能大于防守总次数!');
            }
        });
    }
    // 显示提示信息
    const urlParams = new URLSearchParams(window.location.search);
    if (urlParams.get('success')) {
        showNotification('数据添加成功!', 'success');
    }
    if (urlParams.get('error')) {
        const errors = {
            'successful_defenses_exceed': '成功防守次数不能大于总防守次数',
            'db_error': '数据库错误,请稍后重试'
        };
        const errorMsg = errors[urlParams.get('error')] || '发生错误';
        showNotification(errorMsg, 'error');
    }
    // 排名动画
    animateRanks();
    // 进度条动画
    animateProgressBars();
});
function showNotification(message, type) {
    const notification = document.createElement('div');
    notification.className = `notification ${type}`;
    notification.innerHTML = `
        <span>${message}</span>
        <button onclick="this.parentElement.remove()">×</button>
    `;
    document.body.appendChild(notification);
    setTimeout(() => {
        notification.remove();
    }, 3000);
}
function animateRanks() {
    const ranks = document.querySelectorAll('.rank');
    ranks.forEach((rank, index) => {
        setTimeout(() => {
            rank.classList.add('animated');
        }, index * 100);
    });
}
function animateProgressBars() {
    const bars = document.querySelectorAll('.progress-bar');
    bars.forEach(bar => {
        const targetWidth = bar.style.width;
        bar.style.width = '0%';
        setTimeout(() => {
            bar.style.width = targetWidth;
        }, 300);
    });
}
// 添加CSS动画样式
const style = document.createElement('style');
style.textContent = `
    .rank.animated {
        animation: spinIn 0.5s ease-out;
    }
    @keyframes spinIn {
        from { transform: rotate(0deg) scale(0); }
        to { transform: rotate(360deg) scale(1); }
    }
    .notification {
        position: fixed;
        top: 20px;
        right: 20px;
        padding: 15px 25px;
        border-radius: 8px;
        color: white;
        font-weight: bold;
        box-shadow: 0 4px 6px rgba(0,0,0,0.1);
        z-index: 1000;
        animation: slideIn 0.3s ease-out;
    }
    .notification.success {
        background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
    }
    .notification.error {
        background: linear-gradient(135deg, #dc3545 0%, #f5576c 100%);
    }
    @keyframes slideIn {
        from { transform: translateX(100%); }
        to { transform: translateX(0); }
    }
`;
document.head.appendChild(style);

使用方法

  1. 环境要求:PHP 7.0+、MySQL 5.7+

  2. 安装步骤

    # 导入数据库
    mysql -u root -p < database.sql
    # 将文件部署到PHP服务器
    # 访问 http://localhost/basketball-defense/index.php
  3. 功能特点

    • 📊 实时计算防守成功率
    • 🏆 球员防守排名
    • 📈 可视化数据展示
    • 🎯 综合防守评分
    • 📝 数据录入和管理
    • 🔍 按球员和日期筛选

这个项目提供了完整的人盯人防守成功率分析系统,包含数据录入、统计计算、可视化展示等功能,你可以根据实际需求进行修改和扩展。

上一篇php项目统计区域防守漏洞出现几次?

下一篇当前分类已是最新一篇

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