php项目统计冲刺跑次数谁更多?

wen PHP项目 2

本文目录导读:

php项目统计冲刺跑次数谁更多?

  1. 方案一:基础版(数组存储)
  2. 方案二:数据库版(MySQL)
  3. 方案三:Web界面版
  4. 方案四:命令行版本
  5. 使用建议
  6. 扩展功能想法

我来帮你设计一个统计冲刺跑次数的PHP项目,并提供几种实现方案。

基础版(数组存储)

<?php
class SprintCounter {
    private $records = [];
    // 添加冲刺记录
    public function addSprint($playerName, $distance, $time) {
        if (!isset($this->records[$playerName])) {
            $this->records[$playerName] = [
                'total_sprints' => 0,
                'total_distance' => 0,
                'total_time' => 0,
                'sprint_history' => []
            ];
        }
        $this->records[$playerName]['total_sprints']++;
        $this->records[$playerName]['total_distance'] += $distance;
        $this->records[$playerName]['total_time'] += $time;
        $this->records[$playerName]['sprint_history'][] = [
            'distance' => $distance,
            'time' => $time,
            'timestamp' => date('Y-m-d H:i:s')
        ];
    }
    // 获取所有玩家的冲刺统计
    public function getStatistics() {
        $stats = [];
        foreach ($this->records as $player => $data) {
            $stats[] = [
                'player' => $player,
                'total_sprints' => $data['total_sprints'],
                'total_distance' => $data['total_distance'],
                'avg_time' => $data['total_time'] / $data['total_sprints'],
                'avg_speed' => $data['total_distance'] / $data['total_time']
            ];
        }
        // 按冲刺次数排序
        usort($stats, function($a, $b) {
            return $b['total_sprints'] - $a['total_sprints'];
        });
        return $stats;
    }
    // 找出冲刺次数最多的玩家
    public function findWinner() {
        $stats = $this->getStatistics();
        if (empty($stats)) {
            return null;
        }
        return $stats[0];
    }
}
// 使用示例
$counter = new SprintCounter();
// 模拟数据
$counter->addSprint('张三', 100, 12.5);
$counter->addSprint('李四', 100, 13.2);
$counter->addSprint('张三', 100, 12.1);
$counter->addSprint('王五', 100, 14.0);
$counter->addSprint('李四', 100, 12.8);
$counter->addSprint('张三', 100, 11.9);
$stats = $counter->getStatistics();
$winner = $counter->findWinner();
echo "排名统计:\n";
foreach ($stats as $index => $player) {
    $rank = $index + 1;
    echo "第{$rank}名: {$player['player']} - 冲刺{$player['total_sprints']}次\n";
}
echo "\n🏆 冠军是: {$winner['player']},共冲刺{$winner['total_sprints']}次!\n";
?>

数据库版(MySQL)

<?php
class SprintDatabaseCounter {
    private $pdo;
    public function __construct($host, $dbname, $username, $password) {
        try {
            $this->pdo = new PDO(
                "mysql:host=$host;dbname=$dbname;charset=utf8mb4",
                $username,
                $password,
                [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
            );
            $this->createTables();
        } catch (PDOException $e) {
            die("数据库连接失败: " . $e->getMessage());
        }
    }
    private function createTables() {
        $sql = "
            CREATE TABLE IF NOT EXISTS players (
                id INT AUTO_INCREMENT PRIMARY KEY,
                name VARCHAR(50) NOT NULL UNIQUE
            );
            CREATE TABLE IF NOT EXISTS sprints (
                id INT AUTO_INCREMENT PRIMARY KEY,
                player_id INT NOT NULL,
                distance DECIMAL(5,2),
                time DECIMAL(5,2),
                sprint_date DATETIME DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (player_id) REFERENCES players(id)
            );
        ";
        $this->pdo->exec($sql);
    }
    // 添加冲刺记录
    public function addSprint($playerName, $distance, $time) {
        // 检查并插入玩家
        $stmt = $this->pdo->prepare("INSERT INTO players (name) VALUES (?) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)");
        $stmt->execute([$playerName]);
        $playerId = $this->pdo->lastInsertId();
        // 插入冲刺记录
        $stmt = $this->pdo->prepare("INSERT INTO sprints (player_id, distance, time) VALUES (?, ?, ?)");
        $stmt->execute([$playerId, $distance, $time]);
    }
    // 获取统计排名
    public function getRankings() {
        $sql = "
            SELECT 
                p.name,
                COUNT(s.id) as total_sprints,
                SUM(s.distance) as total_distance,
                ROUND(AVG(s.time), 2) as avg_time,
                ROUND(SUM(s.distance)/SUM(s.time), 2) as avg_speed
            FROM players p
            LEFT JOIN sprints s ON p.id = s.player_id
            GROUP BY p.id, p.name
            ORDER BY COUNT(s.id) DESC
        ";
        return $this->pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
    }
    // 按时间范围统计
    public function getRankingsByDateRange($startDate, $endDate) {
        $sql = "
            SELECT 
                p.name,
                COUNT(s.id) as total_sprints,
                SUM(s.distance) as total_distance,
                ROUND(AVG(s.time), 2) as avg_time
            FROM players p
            LEFT JOIN sprints s ON p.id = s.player_id
                AND s.sprint_date BETWEEN ? AND ?
            GROUP BY p.id, p.name
            ORDER BY COUNT(s.id) DESC
        ";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute([$startDate, $endDate]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
}
?>

Web界面版

<?php
// sprint_app.php - 完整的Web应用
class SprintWebApp {
    private $sessions = [];
    public function __construct() {
        session_start();
        $this->loadData();
    }
    private function loadData() {
        if (isset($_SESSION['sprint_data'])) {
            $this->sessions = json_decode($_SESSION['sprint_data'], true);
        }
    }
    private function saveData() {
        $_SESSION['sprint_data'] = json_encode($this->sessions);
    }
    public function handleRequest() {
        if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
            if ($_POST['action'] === 'add_sprint') {
                $this->addSprint(
                    $_POST['player_name'],
                    $_POST['distance'],
                    $_POST['time']
                );
            } elseif ($_POST['action'] === 'reset') {
                $this->resetData();
            }
        }
    }
    private function addSprint($player, $distance, $time) {
        if (!isset($this->sessions[$player])) {
            $this->sessions[$player] = [
                'count' => 0,
                'total_distance' => 0,
                'total_time' => 0
            ];
        }
        $this->sessions[$player]['count']++;
        $this->sessions[$player]['total_distance'] += $distance;
        $this->sessions[$player]['total_time'] += $time;
        $this->saveData();
    }
    private function resetData() {
        $this->sessions = [];
        $this->saveData();
    }
    public function renderHTML() {
        $winner = $this->findWinner();
        ?>
        <!DOCTYPE html>
        <html>
        <head>
            <title>🏃 冲刺次数统计</title>
            <style>
                body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
                table { width: 100%; border-collapse: collapse; margin: 20px 0; }
                th, td { padding: 12px; border: 1px solid #ddd; text-align: left; }
                th { background-color: #f2f2f2; }
                .input-group { margin: 10px 0; }
                .input-group label { display: inline-block; width: 100px; }
                .btn { padding: 10px 20px; margin: 5px; background: #4CAF50; color: white; border: none; cursor: pointer; }
                .btn:hover { background: #45a049; }
            </style>
        </head>
        <body>
            <h1>🏃 冲刺跑统计系统</h1>
            <div id="winner" class="winner-section">
                <?php if ($winner): ?>
                    <h2>🏆 当前冠军: <?php echo $winner['name']; ?> 
                        (<?php echo $winner['count']; ?>次冲刺)</h2>
                <?php else: ?>
                    <h2>还没有冲刺记录</h2>
                <?php endif; ?>
            </div>
            <div id="entry-form">
                <h3>添加冲刺记录</h3>
                <form method="POST">
                    <input type="hidden" name="action" value="add_sprint">
                    <div class="input-group">
                        <label>选手姓名:</label>
                        <input type="text" name="player_name" required>
                    </div>
                    <div class="input-group">
                        <label>距离(米):</label>
                        <input type="number" name="distance" step="0.01" required>
                    </div>
                    <div class="input-group">
                        <label>时间(秒):</label>
                        <input type="number" name="time" step="0.01" required>
                    </div>
                    <button type="submit" class="btn">添加记录</button>
                </form>
            </div>
            <div id="rankings">
                <h3>排名统计</h3>
                <table>
                    <tr>
                        <th>排名</th>
                        <th>姓名</th>
                        <th>冲刺次数</th>
                        <th>总距离</th>
                        <th>平均速度</th>
                    </tr>
                    <?php foreach ($this->getRankings() as $index => $player): ?>
                    <tr>
                        <td><?php echo $index + 1; ?></td>
                        <td><?php echo $player['name']; ?></td>
                        <td><?php echo $player['count']; ?></td>
                        <td><?php echo $player['total_distance']; ?>m</td>
                        <td><?php echo number_format($player['total_distance'] / $player['total_time'], 2); ?>m/s</td>
                    </tr>
                    <?php endforeach; ?>
                </table>
            </div>
            <form method="POST" onsubmit="return confirm('确定要重置所有数据吗?');">
                <input type="hidden" name="action" value="reset">
                <button type="submit" class="btn">重置所有数据</button>
            </form>
        </body>
        </html>
        <?php
    }
    private function getRankings() {
        $rankings = [];
        foreach ($this->sessions as $name => $data) {
            $rankings[] = [
                'name' => $name,
                'count' => $data['count'],
                'total_distance' => $data['total_distance'],
                'total_time' => $data['total_time']
            ];
        }
        usort($rankings, function($a, $b) {
            return $b['count'] - $a['count'];
        });
        return $rankings;
    }
    private function findWinner() {
        $rankings = $this->getRankings();
        return $rankings[0] ?? null;
    }
}
// 运行应用
$app = new SprintWebApp();
$app->handleRequest();
$app->renderHTML();
?>

命令行版本

<?php
// sprint_cli.php - 命令行交互版本
class SprintCLI {
    private $data = [];
    public function run() {
        echo "=== 冲刺跑统计系统 ===\n";
        while (true) {
            echo "\n选择操作:\n";
            echo "1. 添加冲刺记录\n";
            echo "2. 查看统计\n";
            echo "3. 查看冠军\n";
            echo "4. 退出\n";
            echo "请输入选项 (1-4): ";
            $choice = trim(fgets(STDIN));
            switch ($choice) {
                case '1':
                    $this->addSprint();
                    break;
                case '2':
                    $this->showStats();
                    break;
                case '3':
                    $this->showWinner();
                    break;
                case '4':
                    echo "再见!\n";
                    return;
                default:
                    echo "无效选项,请重试\n";
            }
        }
    }
    private function addSprint() {
        echo "请输入玩家姓名: ";
        $name = trim(fgets(STDIN));
        echo "请输入冲刺距离(米): ";
        $distance = (float)trim(fgets(STDIN));
        echo "请输入冲刺时间(秒): ";
        $time = (float)trim(fgets(STDIN));
        if (!isset($this->data[$name])) {
            $this->data[$name] = [
                'count' => 0,
                'distance' => 0,
                'time' => 0
            ];
        }
        $this->data[$name]['count']++;
        $this->data[$name]['distance'] += $distance;
        $this->data[$name]['time'] += $time;
        echo "✅ 记录成功!{$name} 已冲刺{$this->data[$name]['count']}次\n";
    }
    private function showStats() {
        if (empty($this->data)) {
            echo "暂无记录\n";
            return;
        }
        echo "\n📊 统计结果:\n";
        echo str_pad("排名", 8) . str_pad("姓名", 12) . 
             str_pad("次数", 8) . str_pad("总距离", 10) . 
             str_pad("平均速度", 12) . "\n";
        echo str_repeat("-", 50) . "\n";
        $sorted = $this->sortByCount();
        foreach ($sorted as $index => $player) {
            $avgSpeed = $player['time'] > 0 ? 
                $player['distance'] / $player['time'] : 0;
            echo str_pad($index + 1, 8) . 
                 str_pad($player['name'], 12) . 
                 str_pad($player['count'], 8) . 
                 str_pad($player['distance'] . 'm', 10) . 
                 str_pad(number_format($avgSpeed, 2) . 'm/s', 12) . "\n";
        }
    }
    private function showWinner() {
        if (empty($this->data)) {
            echo "暂无数据\n";
            return;
        }
        $sorted = $this->sortByCount();
        $winner = $sorted[0];
        echo "\n🏆 冠军是: {$winner['name']}\n";
        echo "冲刺次数: {$winner['count']}次\n";
        echo "总距离: {$winner['distance']}米\n";
        echo "平均速度: " . number_format($winner['distance'] / $winner['time'], 2) . "m/s\n";
    }
    private function sortByCount() {
        $sorted = [];
        foreach ($this->data as $name => $info) {
            $info['name'] = $name;
            $sorted[] = $info;
        }
        usort($sorted, function($a, $b) {
            return $b['count'] - $a['count'];
        });
        return $sorted;
    }
}
// 运行CLI程序
$cli = new SprintCLI();
$cli->run();
?>

使用建议

  1. 小规模使用:使用数组版本(方案一)或Web会话版本(方案三)
  2. 正式项目:使用数据库版本(方案二),支持持久化存储
  3. 快速测试:使用CLI版本(方案四)

扩展功能想法

  • 添加图表可视化(使用Chart.js)
  • 支持CSV导入导出
  • 按日期筛选统计
  • 设置冲刺目标并跟踪进度
  • 配置警报(某个玩家突破记录时提醒)

选择最适合你需求的版本,如果还需要特定功能的实现,请告诉我!

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