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 做聚合分析。











