本文目录导读:

我来帮你设计一个统计冲刺跑次数的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();
?>
使用建议
- 小规模使用:使用数组版本(方案一)或Web会话版本(方案三)
- 正式项目:使用数据库版本(方案二),支持持久化存储
- 快速测试:使用CLI版本(方案四)
扩展功能想法
- 添加图表可视化(使用Chart.js)
- 支持CSV导入导出
- 按日期筛选统计
- 设置冲刺目标并跟踪进度
- 配置警报(某个玩家突破记录时提醒)
选择最适合你需求的版本,如果还需要特定功能的实现,请告诉我!