PHP+JS实现电台播放器Now/Next模块曲目结束更新求助
解决电台播放器曲目结束后自动更新「正在播放/即将播放」模块的问题
你的代码目前是服务器端一次性渲染页面,PHP在页面加载时仅查询一次数据库,之后前端没有机制触发重新查询,所以曲目播放结束后无法自动更新模块。同时现有代码还存在SQL注入风险、函数逻辑错误等问题,下面是完整解决方案:
一、修复后端逻辑并创建API接口
首先需要把获取歌曲数据的逻辑改成可通过AJAX调用的接口,同时修复SQL注入和函数错误:
1. 通用歌曲查询函数(避免重复代码)
创建安全的复用函数,使用预处理语句防止SQL注入:
<?php include "connect.php"; // 根据时间获取歌曲信息的通用函数 function getSongByTime($time) { global $mysqli; $song = null; // 使用预处理语句防止SQL注入 $stmt = $mysqli->prepare("SELECT * FROM `music` WHERE `time` = ?"); $stmt->bind_param("s", $time); $stmt->execute(); $result = $stmt->get_result(); if ($row = $result->fetch_assoc()) { $time_now = substr($row["time"], 0, -3); // 返回包含HTML和歌曲信息的数组,避免全局变量 $song = [ 'html' => <<<HTML <div class="block_now_next"> <img class="swiper_img_music" src="{$row["image"]}"> <div> <p class="text_40_swiper">{$row["name"]}</p> <p class="text_36_swiper">{$row["author"]}</p> <p class="text_36_swiper">Слушайте в {$time_now}</p> </div> </div> HTML, 'way' => $row["way"], 'time_next' => $row["time_next"] ]; } $stmt->close(); return $song; } ?>
2. 创建AJAX接口文件(比如get_song_data.php)
这个接口用于前端请求当前和下一曲的数据:
<?php include "connect.php"; include "your_function_file.php"; // 引入上面的通用函数文件 $action = $_GET['action'] ?? ''; $current_time = $_GET['current_time'] ?? '00:00:00'; if ($action === 'current') { $song = getSongByTime($current_time); echo json_encode($song); } elseif ($action === 'next') { // 先获取当前歌曲的下一曲时间,再查询下一曲 $current_song = getSongByTime($current_time); if ($current_song) { $next_song = getSongByTime($current_song['time_next']); echo json_encode($next_song); } else { echo json_encode(null); } } ?>
二、修改前端页面,实现自动更新
1. 给「正在播放/即将播放」模块添加ID,方便DOM操作
修改HTML部分,给两个模块的容器加ID:
<div class="now_next"> <div id="current-song-container"> <?php $initial_song = getSongByTime('00:00:00'); echo $initial_song['html']; ?> </div> <div id="next-song-container"> <?php $next_song = getSongByTime($initial_song['time_next']); echo $next_song['html']; ?> </div> </div>
2. 修改前端JS逻辑,监听播放结束事件并更新数据
更新播放器的JS代码,在曲目结束时发送AJAX请求,获取新数据并更新页面:
<div class="player_center"> <div id="player"></div> <script> // 初始化播放器,保存当前歌曲的时间和路径 let currentSongTime = "<?php echo $initial_song['time_next']; ?>"; let player = new Playerjs({id:"player", file:"<?php echo $initial_song['way'] ?>"}); // 监听播放结束事件 document.getElementById('player').addEventListener('end', () => { // 请求新的当前歌曲数据 fetch(`get_song_data.php?action=current¤t_time=${currentSongTime}`) .then(response => response.json()) .then(currentData => { if (!currentData) return; // 更新正在播放模块 document.getElementById('current-song-container').innerHTML = currentData.html; // 请求下一曲数据 return fetch(`get_song_data.php?action=next¤t_time=${currentSongTime}`); }) .then(response => response.json()) .then(nextData => { if (!nextData) return; // 更新即将播放模块 document.getElementById('next-song-container').innerHTML = nextData.html; // 更新播放器的下一曲路径 player.setFile(nextData.way); // 更新当前歌曲时间,用于下一次请求 currentSongTime = nextData.time_next; }) .catch(error => console.error('更新歌曲数据失败:', error)); }); </script> </div>
三、修复现有代码的其他问题
- 移除全局变量:之前的代码滥用
global传递数据,改用函数返回数组的方式更安全、可维护 - SQL注入防护:所有数据库查询都使用预处理语句,避免直接拼接变量到SQL语句中
- 修复函数逻辑错误:原
nextSong函数中WHERE条件错误使用了$time,现在通过通用函数统一处理,确保查询条件正确
内容的提问来源于stack exchange,提问作者NeONovV
相关产品推荐
相关产品推荐

