下载php-PHP通过标头形式下载文件

2023-08-20 0 2,280 百度已收录

本文由php英文网站认证作者:“一朵云”贡献,欢迎加入!

PHP通过header形式下载文件时,无法以ajax的形式提交。 该方法会将标头结果返回给ajax。

(1)下载大文件时,通常需要较长时间。 PHP有一个默认的执行时间,通常是30s。 如果超过这个时间,下载就会失败,所以需要设置超时`set_time_limit(0);`

这句话说明函数执行没有设置超时时间。 另外需要设置的是显存的使用下载php,只需设置`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)下载缓冲区大小,这个可以根据服务器带宽来设置,一般4096就够了

下载php-PHP通过标头形式下载文件

(4)下载时可以在echobuffer后面设置sleep(1)让程序休眠

(5) 在设置header之前下载php,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;
}

下载php-PHP通过标头形式下载文件

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.设置内存限制

4. header 之前的 Ob_clean()

5.设置缓冲区大小

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

介绍:

如果读取任何文件,则可以直接读取数据库配置文件。 这个漏洞很容易理解。 有些程序下载文件或者读取显示文件时,直接在请求上传递读取文件的参数filename,后台程序获取文件路径后直接读取并返回文件路径。 问题是这个参数是用户可控的,你可以直接传入你要读取的文件的路径。

文件读取函数列表如下:file_get-contents()、highlight_file()、fopen()、readfile()、fread()、fgetss()、fgets()、parse_ini_file()、show_source()、show_source( )、file(),除了那些普通的读取文件的函数外,还可以使用一些其他的函数来读取文件,比如文件包含函数include等,可以使用PHP的输入输出流php:// /filter/ 读取文件。

下载php-PHP通过标头形式下载文件

Phpcmsv9在2012年就被曝出任意文件读取漏洞,当时很多公司都因为这个漏洞被入侵。 漏洞文件/phpcms/modules/search/index.phppublic_的get_suggest_keyword函数,代码如下:

公共函数public_get_suggest_keyword(){

$url = $GET['url'].'$q='.$_GET['q'];

$res = @file_get_contents($url);

if(CHARSET != 'gbk'){

$res = iconv('gbk',CHARSET, $res);

回显 $res;

这里可以看到该函数直接从GET参数中获取要获取的URL,然后使用file_get_contents函数读取内容。 如果我们直接提交 ?url=&q=1.php ,那么 file_get_contents(“&q=1.php”) 就会被带到函数中,所以我们无法读取当前文件.php文件,我们需要 ?url=&q=../ .. 在/1.php中再添加两个“../”,并跳过“&q”作为目录。 最后.php文件,漏洞读取数据库配置文件的EXP如下:

下载php-PHP通过标头形式下载文件

index.php?m=search&c=index&a=public_get_suggest_keyword&url=&q=../../phpsso_server/caches/configs/database.php

目前官方已经修复了该漏洞:

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 php 下载php-PHP通过标头形式下载文件 https://www.wkzy.net/game/125847.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务