PHP 并且 AJAX 下载几 MB 的文件会冻结网站

PHP And AJAX Download of a few MB file freezes website

您好,我到处寻找答案,但是 none 我试过的解决方案有帮助

我正在构建的是一个连接到 Youtube 的网站,允许用户搜索视频并将其下载为 MP3 文件。我已经通过搜索等建立了网站,但是我在下载部分遇到了问题(我已经弄清楚如何获取 youtube 音频文件)。音频的格式最初是 audio/mp4 所以我需要将它转换为 mp3 但是首先我需要在服务器上获取文件

所以我在下载页面上制作了一个脚本,向服务器发送 ajax 请求以开始下载文件。然后它每隔几秒就会向不同的页面发送一个请求,以了解进度并在用户正在查看的页面上更新它。

然而,问题是在下载视频时整个网站冻结(所有页面在文件完全下载之前不会加载),因此当脚本试图找出进度时,它无法完全完成。

下载的文件:

<?php
session_start();
if (isset($_GET['yt_vid']) && isset($_GET['yrt'])) {
    set_time_limit(0); // to prevent the script from stopping execution
    include "assets/functions.php";
    define('CHUNK', (1024 * 8 * 1024));
    if ($_GET['yrt'] == "gphj") {
        $vid = $_GET['yt_vid'];
        $mdvid = md5($vid);
        if (!file_exists("assets/videos/" . $mdvid . ".mp4")) { // check if the file already exists, if not proceed to downloading it
            $url = urlScraper($vid); // urlScraper function is a function to get the audio file, it sends a simple curl request and takes less than a second to complete
            if (!isset($_SESSION[$mdvid])) {
                $_SESSION[$mdvid] = array(time(), 0, retrieve_remote_file_size($url));
            }
            $file = fopen($url, "rb");
            $localfile_name = "assets/videos/" . $mdvid . ".mp4"; // The file is stored on the server so it doesnt have to be downloaded every time
            $localfile = fopen($localfile_name, "w");
            $time = time();
            while (!feof($file)) {
                $_SESSION[$mdvid][1] = (int)$_SESSION[$mdvid][1] + 1;
                file_put_contents($localfile_name, fread($file, CHUNK), FILE_APPEND);
            }
            echo "Execution time: " . (time() - $time);
            fclose($file);
            fclose($localfile);
            $result = curl_result($url, "body");
        } else {
            echo "Failed.";
        }
    }
}
?>

我以前也遇到过这个问题,它不起作用的原因是会话只能打开一次进行写入。 您需要做的是修改您的下载脚本,每次写入会话后直接使用session_write_close()

喜欢:

session_start();
if (!isset($_SESSION[$mdvid])) {
    $_SESSION[$mdvid] = array(time(), 0, retrieve_remote_file_size($url));
}
session_write_close();

同时也在

while (!feof($file)) {
    session_start();
    $_SESSION[$mdvid][1] = (int)$_SESSION[$mdvid][1] + 1;
    session_write_close();
    file_put_contents($localfile_name, fread($file, CHUNK), FILE_APPEND);
}