热门IT资讯网

PHP如何使用header方式下载文件?

发表于:2024-11-30 作者:热门IT资讯网编辑
编辑最后更新 2024年11月30日,PHP通过header方式下载文件时,不能使用ajax方式提交,该方式会将header结果返回给ajax(1) 在下载大文件的时候,通常需要很长的时间,PHP有默认执行时间,一般是30s,超过该时间,

PHP通过header方式下载文件时,不能使用ajax方式提交,该方式会将header结果返回给ajax

(1) 在下载大文件的时候,通常需要很长的时间,PHP有默认执行时间,一般是30s,超过该时间,就是下载失败,所以需要设置一下超时时间`set_time_limit(0);`

该语句说明函数执行不设置超时时间。另一个需要设置的就是内存使用,设置`ini_set('memory_limit', '128M');`即可。

(2) 对于下载文件的文件名称,下载下来可能会出现乱码,当然,这种情况出现在文件名包含中文或者特殊字符的情况下,此时,可以设置一下header:

$contentDispositionField = 'Content-Disposition: attachment; '                    . sprintf('filename="%s"; ', basename($file))                          . sprintf("filename*=utf-8''%s", basename($file));   header($contentDispositionField);

(3)下载buffer大小,这个可以根据服务器带宽设置,一般4096就可以

(4)下载时,可以在echo buffer之后设置sleep(1)让程序休眠

(5)在设置header之前,ob_clean()一下,清除缓存区内容

1.强制下载本地文件

function forceDownload($file = ''){    set_time_limit(0);     //超时设置    ini_set('memory_limit', '128M');    //内存大小设置    ob_clean();    header("Pragma: public");    header("Expires: 0");    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");    header("Content-Type: application/force-download");    header("Content-Type: application/octet-stream");    header("Content-Type: application/download");    $contentDispositionField = 'Content-Disposition: attachment; '            . sprintf('filename="%s"; ', basename($file))        . sprintf("filename*=utf-8''%s", basename($file));    //处理文件名称    header($contentDispositionField);    header("Content-Transfer-Encoding: binary");    header("Content-Length: " . filesize($file));    $read_buffer = 4096;                                    //设置buffer大小        $handle = fopen($file, 'rb');        //总的缓冲的字节数        $sum_buffer = 0;        //只要没到文件尾,就一直读取        while (!feof($handle) && $sum_buffer < filesize($file)) {                echo fread($handle, $read_buffer);                $sum_buffer += $read_buffer;        }        //关闭句柄        fclose($handle);        exit;}

2.限制下载速率

/** * @param  $localFile 本地文件 * @param  $saveFileName  另存文件名 * @param  $downloadRate  下载速率 */function download_with_limitRate($localFile = '',$saveFileName = '',$downloadRate = 20.5){        if(file_exists($localFile) && is_file($localFile)) {                ob_clean();                header('Cache-control: private');                header('Content-Type: application/octet-stream');                 header('Content-Length: '.filesize($localFile));                header('Content-Disposition: filename='.$saveFileName);                                flush();                    // 打开文件流                $file = fopen($localFile, "r");                    while(!feof($file)) {                        // 发送当前块到浏览器                        print fread($file, round($downloadRate * 1024));                            // 输出到浏览器                        flush();                        // sleep one second                        sleep(1);                    }                    //关闭文件流                fclose($file);}        else {                die('Error: The file '.$localFile.' does not exist!');        }}

3.下载网络文件

function downloadFromUrl($url = '', $savePath = 'uploads/'){    set_time_limit(0);    ini_set('max_execution_time', '0');    $pi = pathinfo($url);    $ext = $pi['extension'];    $name = $pi['filename'];    $ch = curl_init();    curl_setopt($ch, CURLOPT_URL, $url);    curl_setopt($ch, CURLOPT_HEADER, false);    curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);    curl_setopt($ch, CURLOPT_AUTOREFERER, true);    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);    $opt = curl_exec($ch);    curl_close($ch);    $saveFile = $name . '.' . $ext;    if (preg_match("/[^0-9a-z._-]/i", $saveFile)) {        $saveFile = $savePath . '/' . md5(microtime(true)) . '.' . $ext;    } else {        $saveFile = $savePath . '/' . $name . '.' . $ext;    }    $handle = fopen($saveFile, 'wb');    if(fwrite($handle, $opt)){        echo 'download success';    }    fclose($handle);    exit;}

4.获取网络文件大小

function remote_filesize($url, $user = "", $pw = ""){    ob_start();    $ch = curl_init($url);    curl_setopt($ch, CURLOPT_HEADER, 1);    curl_setopt($ch, CURLOPT_NOBODY, 1);    if (!empty($user) && !empty($pw)) {        $headers = array('Authorization: Basic ' . base64_encode("$user:$pw"));        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);    }    curl_exec($ch);    curl_close($ch);    $head = ob_get_contents();    ob_end_clean();    $regex = '/Content-Length:\s([0-9].+?)\s/';    preg_match($regex, $head, $matches);    return isset($matches[1]) ? $matches[1] : "unknown";}

总结:

1.通过header方式下载一定不能通过ajax方式请求

2.设置超时时间

3.设置memory_limit

4.在header之前ob_clean()

5.设置buffer大小

6.可以设置sleep()减轻内存压力

以上就是PHP通过header方式下载文件教程的详细内容,更多请关注其它相关文章!

0