Heim > php教程 > php手册 > PHP实现点击a标签的href做链接时,直接保存文件(任何类型),而

PHP实现点击a标签的href做链接时,直接保存文件(任何类型),而

WBOY
Freigeben: 2016-06-06 19:59:47
Original
1246 Leute haben es durchsucht

一、 index.php中: ?php echo a href='process.php?filename=halo.mp3'下载/a? process.php中: ?php header(Content-type: application/octet-stream);header('Content-Disposition: attachment; filename='. basename($_GET['filename']).'');header(Cont

一、

index.php中:

<?php echo "<a href='process.php?filename=halo.mp3'>下载"
?>
Nach dem Login kopieren

process.php中:
<?php header("Content-type: application/octet-stream");

	header('Content-Disposition: attachment; filename="'. basename($_GET['filename']).'"');

	header("Content-Length: ". filesize($_GET['filename']));

	readfile($_GET['filename']);
?>
Nach dem Login kopieren

这是最简单的方法,但是有个问题:如果请求的路径中包含中文,那么下载的文件名有可能就是乱码。

二、

针对上面问题的解决方案,index.php中:

<?php echo "<a href='process.php?filename=halo光环.mp3'>下载"
?>
Nach dem Login kopieren

process.php中:
<?php header("Content-type: application/octet-stream");

	//处理中文文件名

	$ua = $_SERVER["HTTP_USER_AGENT"];

	$encoded_filename = urlencode($_GET['filename']);

	$encoded_filename = str_replace("+", "%20", $encoded_filename);

	if (preg_match("/MSIE/", $ua)) {

	header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');

	} else if (preg_match("/Firefox/", $ua)) {

	header("Content-Disposition: attachment; filename*=\"utf8''" . $_GET['filename'] . '"');

	} else {

	header('Content-Disposition: attachment; filename="' . $_GET['filename'] . '"');

	}

	header("Content-Length: ". filesize($_GET['filename']));

	readfile($_GET['filename']);
?>
Nach dem Login kopieren

输出的时候,如果是Apache+PHP,那么还需要发送到Apache的输出缓冲区,最后才发送给用户。而对于Nginx+fpm,如果它们分开部署的话,那还会带来额外的网络IO。

三、

现在貌似没有问题了,但是readfile还是有问题的,虽然PHP的readfile尝试实现的尽量高效,不占用PHP本身的内存,但是实际上它还是需要采用MMAP(如果支持),或者是一个固定的buffer去循环读取文件,直接输出。

那么能不能绕过PHP这层呢,直接由webserver把文件发送给用户呢?可以的,我们可以使用Apache的module mode_xsendfile,让Apache直接发送这个文件给用户。

代码实现如下:(process.php)

header("Content-type: application/octet-stream");

//处理中文文件名

$ua = $_SERVER["HTTP_USER_AGENT"];

$encoded_filename = urlencode($_GET['filename']);

$encoded_filename = str_replace("+", "%20", $encoded_filename);

if (preg_match("/MSIE/", $ua)) {

header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');

} else if (preg_match("/Firefox/", $ua)) {

header("Content-Disposition: attachment; filename*=\"utf8''" . $_GET['filename'] . '"');

} else {

header('Content-Disposition: attachment; filename="' . $_GET['filename'] . '"');

}

//让Xsendfile发送文件
  header("X-Sendfile: $_GET['filename']"); 
Nach dem Login kopieren

最后,如果愿意的话,可以先判断后缀,因为有时候图片当成文件下载也会引起一些不方便的:
       $type = strrchr($_GET['filename'], "."); //获取后缀 
       if($type == "jpg" || "png" || "gif"){ 
       header("Content-Disposition: filename=$_GET['filename']"); //这里我试过,加引号的话,下载时会加到文件名中 
       header("Content-Type: image/$type"); 
       }
Nach dem Login kopieren





Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Empfehlungen
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage