本文目录导读:

在PHP项目中统计SofaScore综合评分,通常需要从SofaScore API获取球员或球队的评分数据,以下是完整的实现方案:
获取SofaScore API数据
API认证和请求配置
<?php
class SofaScoreAPI {
private $apiKey;
private $baseUrl = 'https://api.sofascore.com/api/v1';
private $headers;
public function __construct($apiKey) {
$this->apiKey = $apiKey;
$this->headers = [
'Authorization: Bearer ' . $apiKey,
'Accept: application/json',
'User-Agent: MyFootballApp/1.0'
];
}
/**
* 获取球员评分数据
* @param int $playerId 球员ID
* @return array 球员评分数据
*/
public function getPlayerRatings($playerId) {
$url = $this->baseUrl . "/player/{$playerId}/ratings";
return $this->makeRequest($url);
}
/**
* 获取球队球员评分列表
* @param int $teamId 球队ID
* @param int $seasonId 赛季ID
* @return array 球员评分列表
*/
public function getTeamPlayerRatings($teamId, $seasonId) {
$url = $this->baseUrl . "/team/{$teamId}/players/{$seasonId}";
return $this->makeRequest($url);
}
/**
* 获取比赛评分
* @param int $eventId 比赛事件ID
* @return array 比赛评分数据
*/
public function getEventRatings($eventId) {
$url = $this->baseUrl . "/event/{$eventId}/ratings";
return $this->makeRequest($url);
}
private function makeRequest($url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("API请求失败: HTTP {$httpCode}");
}
return json_decode($response, true);
}
}
综合评分统计模型
<?php
class SofaScoreRatingAggregator {
// 评分权重配置
private $weights = [
'matches' => 0.4, // 出场次数权重
'avg_rating' => 0.3, // 平均评分权重
'consistency' => 0.2, // 稳定性权重
'trend' => 0.1 // 近期趋势权重
];
/**
* 计算球员综合评分
* @param array $playerRatings 球员评分数据
* @return array 综合评分结果
*/
public function calculateCompositeRating($playerRatings) {
if (empty($playerRatings) || empty($playerRatings['data'])) {
return null;
}
$data = $playerRatings['data'];
// 基础统计
$matches = count($data);
$sum = 0;
$ratings = [];
foreach ($data as $match) {
if (isset($match['rating']) && $match['rating'] > 0) {
$sum += $match['rating'];
$ratings[] = $match['rating'];
}
}
$avgRating = $matches > 0 ? round($sum / $matches, 2) : 0;
// 稳定性(标准差计算)
$consistency = $this->calculateConsistency($ratings, $avgRating);
// 近期趋势(最近5场比赛)
$trend = $this->calculateTrend($ratings);
// 综合评分计算
$compositeScore = (
$matches * $this->weights['matches'] +
$avgRating * $this->weights['avg_rating'] +
$consistency * $this->weights['consistency'] +
$trend * $this->weights['trend']
);
// 规范化为1-10分制
$compositeScore = min(10, max(1, $compositeScore));
return [
'composite_score' => round($compositeScore, 2),
'matches_played' => $matches,
'avg_rating' => $avgRating,
'consistency_score' => round($consistency, 2),
'trend_score' => round($trend, 2),
'max_rating' => max($ratings),
'min_rating' => min($ratings),
'last_matches' => array_slice($ratings, -5)
];
}
/**
* 计算稳定性分数
* @param array $ratings 评分数组
* @param float $avg 平均评分
* @return float 稳定性得分
*/
private function calculateConsistency($ratings, $avg) {
if (count($ratings) < 1) {
return 0;
}
$variance = 0;
$n = count($ratings);
foreach ($ratings as $rating) {
$variance += pow($rating - $avg, 2);
}
$stdDev = sqrt($variance / $n);
// 标准差越小稳定性越高,转换为10分制
$consistencyScore = 10 - ($stdDev * 5);
return max(1, min(10, $consistencyScore));
}
/**
* 计算近期趋势
* @param array $ratings 评分数组
* @return float 趋势得分
*/
private function calculateTrend($ratings) {
if (count($ratings) < 3) {
return 5; // 数据不足时返回中等分数
}
// 取最近5场(或所有)比赛
$recentMatches = array_slice($ratings, -5);
$n = count($recentMatches);
if ($n < 2) {
return 5;
}
// 简单线性回归计算趋势
$x = range(1, $n);
$xAvg = array_sum($x) / $n;
$yAvg = array_sum($recentMatches) / $n;
$numerator = 0;
$denominator = 0;
for ($i = 0; $i < $n; $i++) {
$numerator += ($x[$i] - $xAvg) * ($recentMatches[$i] - $yAvg);
$denominator += pow($x[$i] - $xAvg, 2);
}
if ($denominator == 0) {
return 5;
}
$slope = $numerator / $denominator;
// 将斜率转换为趋势分数 (0-10)
$trendScore = 5 + ($slope * 2);
return max(1, min(10, $trendScore));
}
}
数据存储模块
<?php
class RatingRepository {
private $db;
public function __construct($dbConnection) {
$this->db = $dbConnection;
}
/**
* 保存球员评分数据
*/
public function savePlayerRating($playerId, $teamId, $eventId, $rating, $matchDate) {
$sql = "INSERT INTO player_ratings
(player_id, team_id, event_id, rating, match_date)
VALUES (?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE rating = VALUES(rating)";
$stmt = $this->db->prepare($sql);
return $stmt->execute([$playerId, $teamId, $eventId, $rating, $matchDate]);
}
/**
* 获取球员历史评分
*/
public function getPlayerRatings($playerId, $limit = 30) {
$sql = "SELECT rating, match_date
FROM player_ratings
WHERE player_id = ?
ORDER BY match_date DESC
LIMIT ?";
$stmt = $this->db->prepare($sql);
$stmt->execute([$playerId, $limit]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
/**
* 获取球员综合评分缓存
*/
public function getCachedCompositeRating($playerId) {
$sql = "SELECT composite_score FROM player_composite_ratings
WHERE player_id = ?
AND updated_at > DATE_SUB(NOW(), INTERVAL 24 HOUR)";
$stmt = $this->db->prepare($sql);
$stmt->execute([$playerId]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return $result ? $result['composite_score'] : null;
}
/**
* 缓存综合评分
*/
public function cacheCompositeRating($playerId, $compositeScore) {
$sql = "INSERT INTO player_composite_ratings (player_id, composite_score, updated_at)
VALUES (?, ?, NOW())
ON DUPLICATE KEY UPDATE composite_score = VALUES(composite_score), updated_at = NOW()";
$stmt = $this->db->prepare($sql);
return $stmt->execute([$playerId, $compositeScore]);
}
}
使用示例
<?php
// 配置文件
$config = [
'api_key' => 'your_sofascore_api_key',
'db_host' => 'localhost',
'db_name' => 'football_stats',
'db_user' => 'root',
'db_pass' => 'password'
];
// 初始化数据库连接
$db = new PDO(
"mysql:host={$config['db_host']};dbname={$config['db_name']}",
$config['db_user'],
$config['db_pass']
);
// 初始化API和聚合器
$api = new SofaScoreAPI($config['api_key']);
$aggregator = new SofaScoreRatingAggregator();
$repository = new RatingRepository($db);
// 获取球员综合评分
function getPlayerCompositeRating($playerId) {
global $api, $aggregator, $repository;
// 检查缓存
$cachedScore = $repository->getCachedCompositeRating($playerId);
if ($cachedScore !== null) {
return $cachedScore;
}
try {
// 获取评分数据
$ratingsData = $api->getPlayerRatings($playerId);
// 计算综合评分
$compositeRating = $aggregator->calculateCompositeRating($ratingsData);
if ($compositeRating) {
// 缓存计算结果
$repository->cacheCompositeRating($playerId, $compositeRating['composite_score']);
}
return $compositeRating;
} catch (Exception $e) {
// 记录错误日志
error_log("获取球员评分失败: " . $e->getMessage());
return null;
}
}
// 使用示例
$playerId = 12345;
$compositeRating = getPlayerCompositeRating($playerId);
if ($compositeRating) {
echo "球员综合评分: " . $compositeRating['composite_score'] . "\n";
echo "出场次数: " . $compositeRating['matches_played'] . "\n";
echo "平均评分: " . $compositeRating['avg_rating'] . "\n";
echo "稳定性: " . $compositeRating['consistency_score'] . "\n";
echo "趋势: " . $compositeRating['trend_score'] . "\n";
} else {
echo "无法获取评分数据\n";
}
数据库表结构
-- 球员评分表
CREATE TABLE player_ratings (
id INT AUTO_INCREMENT PRIMARY KEY,
player_id INT NOT NULL,
team_id INT,
event_id INT,
rating DECIMAL(3,1),
match_date DATE,
UNIQUE KEY unique_player_match (player_id, event_id),
INDEX idx_player_date (player_id, match_date)
);
-- 综合评分缓存表
CREATE TABLE player_composite_ratings (
player_id INT PRIMARY KEY,
composite_score DECIMAL(3,1),
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_updated (updated_at)
);
-- 球员信息表(可选)
CREATE TABLE players (
id INT PRIMARY KEY,
name VARCHAR(100),
team_id INT,
position VARCHAR(20),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
注意事项
- API限制:SofaScore API有请求频率限制,建议使用缓存减少API调用
- 数据时效性:评分数据每场比赛后更新,建议定期同步
- 错误处理:API可能会返回错误或限流,需要有完善的错误处理机制
- 多维度评分:可以根据需要扩展评分维度(如位置权重、比赛重要性等)
- 前端显示:可以使用图表库(如Chart.js)展示评分趋势
这个方案提供了完整的SofaScore综合评分统计功能,可以根据实际需求进行调整和扩展。