本文目录导读:

在PHP项目中统计“犯规战术阻止反击”的次数,通常需要结合业务逻辑和数据模型来设计,由于“犯规战术”和“反击”属于足球/篮球比赛数据分析的术语,我提供两种常见的实现方案,你可以根据项目具体情况选择。
基于数据库字段统计(推荐,适合已有比赛数据表)
如果你的项目中有 match_events(比赛事件表),通常包含类似 event_type(事件类型)和 related_event_id(关联事件ID)字段。
思路: 一条“犯规”记录如果关联了“反击”事件,并且该反击最终没有形成进球(或射门),则计为一次“成功阻止”。
SQL 查询示例:
SELECT
COUNT(*) AS block_counter_attack_count
FROM
match_events AS fa
INNER JOIN
match_events AS ca ON fa.match_id = ca.match_id
AND ca.event_type = 'counter_attack'
AND ca.id = fa.related_event_id
WHERE
fa.event_type = 'foul'
-- 关键条件:该反击没有形成进球
AND ca.event_result != 'goal';
PHP 代码(使用 PDO + MySQL):
<?php
function getBlockCounterAttackCount(PDO $pdo, int $matchId): int
{
$sql = "
SELECT COUNT(*) as cnt
FROM match_events fa
INNER JOIN match_events ca
ON fa.match_id = ca.match_id
AND ca.id = fa.related_event_id
WHERE fa.match_id = :match_id
AND fa.event_type = 'foul'
AND ca.event_type = 'counter_attack'
AND ca.event_result != 'goal'
";
$stmt = $pdo->prepare($sql);
$stmt->execute([':match_id' => $matchId]);
return (int)$stmt->fetchColumn();
}
// 使用示例
$matchId = 123;
$count = getBlockCounterAttackCount($pdo, $matchId);
echo "本场阻止反击次数: " . $count;
?>
基于 PHP 数组/对象逻辑统计(适合实时内存统计数据)
如果你的项目在比赛中实时统计数据,通常会将事件加载到内存中,然后用PHP数组函数进行过滤。
思路:
遍历事件数组,找到所有标记为“犯规”的事件,检查其 related_event 是否为“反击”,且反击未成功。
PHP 代码示例:
<?php
/**
* 统计阻止反击次数
* @param array $events 比赛事件列表
* @return int
*/
function countBlockedCounterAttacks(array $events): int
{
$count = 0;
foreach ($events as $event) {
// 1. 检查当前事件是否是犯规
if ($event['event_type'] !== 'foul') {
continue;
}
// 2. 找到关联的反击事件
$relatedEvent = findEventById($events, $event['related_id'] ?? null);
if ($relatedEvent === null) {
continue;
}
// 3. 确认是反击事件且反击失败
if ($relatedEvent['event_type'] === 'counter_attack'
&& $relatedEvent['result'] !== 'goal') {
$count++;
}
}
return $count;
}
/**
* 根据ID查找事件
*/
function findEventById(array $events, ?int $id): ?array
{
if ($id === null) return null;
foreach ($events as $event) {
if ($event['id'] === $id) {
return $event;
}
}
return null;
}
// 模拟数据
$events = [
['id' => 1, 'event_type' => 'counter_attack', 'result' => 'shot_on_target'], // 反击射正
['id' => 2, 'event_type' => 'foul', 'related_id' => 1], // 犯规阻止了这次反击
['id' => 3, 'event_type' => 'counter_attack', 'result' => 'goal'], // 这次反击进球了
['id' => 4, 'event_type' => 'foul', 'related_id' => 3], // 犯规但没阻止成功
['id' => 5, 'event_type' => 'counter_attack', 'result' => 'out'], // 反击出界
['id' => 6, 'event_type' => 'foul', 'related_id' => 5], // 犯规导致反击结束
];
echo countBlockedCounterAttacks($events); // 输出: 2
?>
关键扩展(进阶需求)
如果你的统计需要区分战术犯规(专门破坏快攻)和普通犯规,建议在 foul 事件中添加一个布尔字段 is_tactical。
数据库迁移建议:
ALTER TABLE match_events ADD COLUMN is_tactical BOOLEAN DEFAULT FALSE;
修改后的统计条件:
// 在 WHERE 中加上 AND fa.is_tactical = TRUE
性能优化建议
- 索引:在
match_events表上,给(match_id, event_type, related_id)建立联合索引。 - 缓存:如果一场比赛只统计一次,可以考虑将结果缓存到 Redis 或内存中,避免重复查询。
如果你的项目数据结构有所不同(比如存储 JSON 字段),可以补充说明,我会提供对应解决方案。