http force header不能与上面的< 2GB文件

时间:2017-04-03 20:33:15

标签: php

我有一个脚本,用于下载pdf和媒体格式的大文件。我无法下载它会发出http内部错误,有时它会给出500内部服务器错误。

<?php


//The directory where the download files are kept - keep outside of the web document root
$strDownloadFolder = "uploads/";

//If you can download a file more than once
$boolAllowMultipleDownload = 0;

// 1. Create a database connection
//connect to the DB
$resDB = mysql_connect("localhost", "root", "");
mysql_select_db("downloader", $resDB);


if(!empty($_GET['key'])){
    //check the DB for the key
    $resCheck = mysql_query("SELECT * FROM downloads WHERE downloadkey = '".mysql_real_escape_string($_GET['key'])."' LIMIT 1");
    if($resCheck == FALSE) { echo "QUERY FAILED: " . mysql_error(); }
    $arrCheck = mysql_fetch_assoc($resCheck);
    if(!empty($arrCheck['file'])){
        //check that the download time hasnt expired
        if($arrCheck['expires']>=time()){
            if(!$arrCheck['downloads'] OR $boolAllowMultipleDownload){
                //everything is hunky dory - check the file exists and then let the user download it
                $strDownload = $strDownloadFolder.$arrCheck['file'];

                if(file_exists($strDownload)){

                    //get the file content
                    $strFile = file_get_contents($strDownload);

                    //set the headers to force a download
                    header("Content-type: application/force-download");
                    header("Content-Disposition: attachment; filename=\"".str_replace(" ", "_", $arrCheck['file'])."\"");

                    //echo the file to the user
                    echo $strFile;

                    //update the DB to say this file has been downloaded
                    mysql_query("UPDATE downloads SET downloads = downloads + 1 WHERE downloadkey = '".mysqli_real_escape_string($_GET['key'])."' LIMIT 1");

                    exit;

                }else{
                    echo "We couldn't find the file to download.";
                }
            }else{
                //this file has already been downloaded and multiple downloads are not allowed
                echo "This file has already been downloaded.";
            }
        }else{
            //this download has passed its expiry date
            echo "This download has expired.";
        }
    }else{
        //the download key given didnt match anything in the DB
        echo "No file was found to download.";
    }
}else{
    //No download key wa provided to this script
    echo "No download key was provided. Please return to the previous page and try again.";
}

?>

由于http force标头不适用于较大的文件...我想使用带有download属性的href,所以当用户点击它时它应该有直接加密的链接!有令牌或有限会话!

1 个答案:

答案 0 :(得分:0)

file_get_contents将整个文件读入内存。如果文件大于可用内存,则会失败。

相反,您可以直接将文件内容读取到输出流:

//read whole file into memory, whoops
//$strFile = file_get_contents($strDownload);

//set the headers to force a download
header("Content-type: application/force-download");
header("Content-Disposition: attachment; filename=\"".str_replace(" ", "_", $arrCheck['file'])."\"");

//read file to output stream
readfile($strDownload);

http://php.net/manual/en/function.readfile.php