php无法直接检测视频播放状态,因其运行在服务端,只能通过前端javaScript监听事件并上报数据,再由PHP接口接收、校验、存储。

PHP 无法直接检测视频播放状态
PHP 是服务端脚本语言,运行在服务器上,不接触浏览器的播放器或 dom。它无法知道用户是否在播放、暂停、拖拽或卡顿——这些行为发生在前端,PHP 没有实时访问能力。所谓“PHP 检测播放状态”,本质是前端主动上报 + PHP 接收记录,而非 PHP 主动探测。
用 javascript 监听事件并 POST 到 PHP 接口
真实可行的做法是:在页面中用 video 元素配合 js 监听 play、pause、timeupdate 等事件,再通过 fetch 或 XMLhttpRequest 把状态发给 PHP 后端接口处理。
常见上报字段包括:video_id、Event(如 "play")、current_time、duration、user_id(需登录态)等。
容易踩的坑:
立即学习“PHP免费学习笔记(深入)”;
- 未节流
timeupdate,导致每秒发十几次请求,压垮 PHP 接口 - 没校验
Referer或加 Token,被恶意刷接口 - PHP 接口没做幂等处理,重复上报造成数据冗余
- 忽略跨域问题,前端报
CORS错误
fetch('/api/log-video-event.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ video_id: 'vid_123', event: 'play', current_time: Math.floor(video.currentTime), user_id: 456 }) });
PHP 接口如何安全接收并存入数据库
log-video-event.php 需做基础防护和结构化存储,不能裸收 raw data。
关键操作:
- 检查
$_SERVER['REQUEST_METHOD'] === 'POST' - 用
json_decode(file_get_contents('php://input'), true)解析 body - 校验必要字段是否存在且类型合法(如
current_time是 int,event在预设白名单内) - 用 pdo 预处理插入,防 sql 注入
- 建议加 redis 缓存去重(例如 5 秒内相同
video_id+user_id+event只记一次)
'Method not allowed']); exit; } $data = json_decode(file_get_contents('php://input'), true); if (!$data || !isset($data['video_id'], $data['event'], $data['user_id'])) { http_response_code(400); echo json_encode(['error' => 'Missing required fields']); exit; } // 白名单校验 $allowed_events = ['play', 'pause', 'ended', 'seeking']; if (!in_array($data['event'], $allowed_events)) { http_response_code(400); echo json_encode(['error' => 'Invalid event']); exit; } // PDO 插入示例(需自行配置 $pdo) $stmt = $pdo->prepare("INSERT INTO video_logs (video_id, user_id, event, current_time, created_at) VALUES (?, ?, ?, ?, NOW())"); $stmt->execute([$data['video_id'], $data['user_id'], $data['event'], (int)$data['current_time']]); echo json_encode(['ok' => true]);
为什么不能用 PHP 的 file_exists 或 get_headers 判断视频能否播放
有人误以为用 file_exists() 或 get_headers() 检查视频 URL 是否返回 200,就算“检测播放状态”——这只能说明文件可访问,完全不等于能正常播放。
真正影响播放的因素 PHP 无法覆盖:
- 前端解码能力(如 safari 不支持 AV1)
- 网络抖动导致
stalled事件 - DRM 授权过期
- 视频编码参数超出浏览器支持范围(如 HEVC Profile > Main 10)
- HTTP 范围请求(
Rangeheader)未正确响应,拖拽失败
这些必须靠前端 video.Error、onstalled、oncanplaythrough 等事件捕获,并上报给 PHP 做聚合分析。