本文目录导读:

我来帮你设计一个PHP项目统计界外球进攻威胁次数的方案。
数据库设计
-- 界外球事件表
CREATE TABLE throw_in_events (
id INT PRIMARY KEY AUTO_INCREMENT,
match_id INT NOT NULL,
team_id INT NOT NULL,
player_id INT,
period INT COMMENT '上半场/下半场',
minute INT COMMENT '发生时间',
field_area VARCHAR(50) COMMENT '球场区域',
threat_level TINYINT COMMENT '威胁等级1-5',
is_threat BOOLEAN DEFAULT FALSE,
threat_type VARCHAR(50) COMMENT '威胁类型',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_match (match_id),
INDEX idx_team (team_id)
);
-- 球队表(示例)
CREATE TABLE teams (
id INT PRIMARY KEY AUTO_INCREMENT,
team_name VARCHAR(100) NOT NULL,
country VARCHAR(50)
);
-- 球员表(示例)
CREATE TABLE players (
id INT PRIMARY KEY AUTO_INCREMENT,
team_id INT,
player_name VARCHAR(100),
position VARCHAR(50)
);
核心PHP类设计
<?php
class ThrowInThreatAnalyzer {
private $db;
public function __construct($pdo) {
$this->db = $pdo;
}
/**
* 记录界外球事件
*/
public function recordThrowIn($matchId, $teamId, $playerId, $data) {
$sql = "INSERT INTO throw_in_events
(match_id, team_id, player_id, period, minute, field_area,
threat_level, is_threat, threat_type)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = $this->db->prepare($sql);
return $stmt->execute([
$matchId,
$teamId,
$playerId,
$data['period'],
$data['minute'],
$data['field_area'],
$data['threat_level'],
$data['threat_level'] >= 3, // 3级以上算威胁
$this->determineThreatType($data['field_area'], $data['threat_level'])
]);
}
/**
* 判断威胁类型
*/
private function determineThreatType($fieldArea, $threatLevel) {
$threatAreas = ['禁区左侧', '禁区右侧', '禁区前沿'];
if (in_array($fieldArea, $threatAreas) && $threatLevel >= 4) {
return 'high_danger';
} elseif (in_array($fieldArea, $threatAreas)) {
return 'dangerous';
} elseif ($threatLevel >= 3) {
return 'potential';
}
return 'none';
}
/**
* 统计某场比赛的威胁次数
*/
public function getMatchThreatStats($matchId, $teamId = null) {
$sql = "SELECT
COUNT(*) as total_throws,
SUM(CASE WHEN is_threat = 1 THEN 1 ELSE 0 END) as threat_count,
SUM(CASE WHEN threat_type = 'high_danger' THEN 1 ELSE 0 END) as high_threats,
SUM(CASE WHEN threat_type = 'dangerous' THEN 1 ELSE 0 END) as medium_threats,
AVG(threat_level) as avg_threat_level,
GROUP_CONCAT(threat_type) as threat_types
FROM throw_in_events
WHERE match_id = ?";
$params = [$matchId];
if ($teamId) {
$sql .= " AND team_id = ?";
$params[] = $teamId;
}
$stmt = $this->db->prepare($sql);
$stmt->execute($params);
return $stmt->fetch(PDO::FETCH_ASSOC);
}
/**
* 按区域统计威胁分布
*/
public function getThreatByArea($matchId) {
$sql = "SELECT
field_area,
COUNT(*) as total,
SUM(CASE WHEN is_threat = 1 THEN 1 ELSE 0 END) as threats,
SUM(CASE WHEN threat_level >= 4 THEN 1 ELSE 0 END) as critical
FROM throw_in_events
WHERE match_id = ?
GROUP BY field_area
ORDER BY threats DESC";
$stmt = $this->db->prepare($sql);
$stmt->execute([$matchId]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
/**
* 获取给定时间段的威胁趋势
*/
public function getThreatTrend($matchId, $intervalMinutes = 15) {
$sql = "SELECT
CASE
WHEN minute BETWEEN 0 AND ? THEN '0-15'
WHEN minute BETWEEN ? AND ? THEN '15-30'
WHEN minute BETWEEN ? AND ? THEN '30-45'
WHEN minute BETWEEN ? AND ? THEN '45-60'
WHEN minute BETWEEN ? AND ? THEN '60-75'
ELSE '75-90'
END as time_range,
COUNT(*) as throws,
SUM(CASE WHEN is_threat = 1 THEN 1 ELSE 0 END) as threats
FROM throw_in_events
WHERE match_id = ?
GROUP BY time_range
ORDER BY MIN(minute)";
$stmt = $this->db->prepare($sql);
$stmt->execute([15, 15, 30, 30, 45, 45, 60, 60, 75, $matchId]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
/**
* 计算威胁转化率
*/
public function getThreatConversionRate($matchId, $teamId = null) {
$stats = $this->getMatchThreatStats($matchId, $teamId);
if ($stats['total_throws'] == 0) {
return 0;
}
return round(($stats['threat_count'] / $stats['total_throws']) * 100, 2);
}
/**
* 球员威胁贡献度分析
*/
public function getPlayerThreatAnalysis($matchId) {
$sql = "SELECT
p.player_name,
COUNT(t.id) as total_throws,
SUM(CASE WHEN t.is_threat = 1 THEN 1 ELSE 0 END) as threats,
AVG(t.threat_level) as avg_threat,
MAX(t.threat_level) as max_threat
FROM throw_in_events t
JOIN players p ON t.player_id = p.id
WHERE t.match_id = ? AND t.is_threat = 1
GROUP BY t.player_id, p.player_name
ORDER BY threats DESC
LIMIT 10";
$stmt = $this->db->prepare($sql);
$stmt->execute([$matchId]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
/**
* 实时威胁检测(简化版)
*/
public function calculateRealTimeThreat($data) {
$score = 0;
// 距离球门越近,威胁越大
$distanceScores = [
'本方半场' => 1,
'中场' => 2,
'前场' => 3,
'禁区前沿' => 4,
'禁区内' => 5,
'禁区两侧' => 4
];
$score += $distanceScores[$data['field_area']] ?? 2;
// 配合位置加分
if (isset($data['in_attack_phase'])) {
$score += 1;
}
// 人数优势加分
if (isset($data['numbers_advantage']) && $data['numbers_advantage']) {
$score += 1;
}
// 时间因素(比赛末段威胁更大)
if (isset($data['minute']) && $data['minute'] > 80) {
$score += 0.5;
}
return min(5, round($score));
}
}
使用示例
<?php
// 初始化
$pdo = new PDO('mysql:host=localhost;dbname=football', 'user', 'password');
$analyzer = new ThrowInThreatAnalyzer($pdo);
// 1. 记录一次界外球
$analyzer->recordThrowIn(1, 1, 10, [
'period' => 1,
'minute' => 25,
'field_area' => '禁区右侧',
'threat_level' => 4
]);
// 2. 统计全场威胁
$stats = $analyzer->getMatchThreatStats(1);
print_r($stats);
// 3. 查看特定球队
$teamStats = $analyzer->getMatchThreatStats(1, 1);
echo "威胁次数: " . $teamStats['threat_count'];
// 4. 威胁转化率
$rate = $analyzer->getThreatConversionRate(1, 1);
echo "转化率: " . $rate . "%";
// 5. 区域分布
$areas = $analyzer->getThreatByArea(1);
foreach ($areas as $area) {
echo "{$area['field_area']}: {$area['threats']}次威胁\n";
}
// 6. 时间趋势
$trends = $analyzer->getThreatTrend(1);
foreach ($trends as $trend) {
echo "{$trend['time_range']}: {$trend['threats']}次威胁\n";
}
前端展示建议
<!-- 威胁统计卡片 -->
<div class="threat-card">
<h3>界外球威胁统计</h3>
<div class="stats-grid">
<div class="stat">
<span class="label">总界外球</span>
<span class="value"><?php echo $stats['total_throws']; ?></span>
</div>
<div class="stat">
<span class="label">威胁次数</span>
<span class="value"><?php echo $stats['threat_count']; ?></span>
</div>
<div class="stat">
<span class="label">高威胁</span>
<span class="value"><?php echo $stats['high_threats']; ?></span>
</div>
<div class="stat">
<span class="label">平均威胁度</span>
<span class="value"><?php echo number_format($stats['avg_threat_level'], 1); ?></span>
</div>
</div>
</div>
这个系统可以灵活扩展,你可以根据实际需求调整威胁判定逻辑和统计维度,是否需要我补充更具体的功能或样式?
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播