You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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&current_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&current_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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 14:20:00