php实现支持中文的文件下载功能示例


Posted in PHP onAugust 30, 2017

前言

本文主要给大家介绍了关于php实现支持中文的文件下载功能的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。

问题说明

文件下载,通常有一种最为简单的方法,那就是将url直接指向服务器上文件的所在位置。但是这个方法存在很大的安全隐患。

  • 暴露了服务器文件目录结构
  • 无法禁止非法请求来源,无法对文件下载请求做安全验证

解决方案

一、将文件下载请求映射到后端程序url

借助http服务器(apache/nginx)实现映射功能

这里以apache为例进行说明

借助apache的rewrite模块,配置rewrite规则。(关于如何开启rewrite模块,网上很多资源,这里不再赘诉)
在项目根目录下创建.htaccess文件,写入rewrite规则

RewriteEngine on
#将所有以rar/zip结尾的url,映射给download.php文件
RewriteRule (.*\.(rar|zip))$ download.php?file=$1 [NC]

将所有以rar/zip结尾的url,映射给download.php文件(这里为了方便直接映射到了一个php脚本中,如果是使用框架,那就映射到具体的控制器中的某个方法!例如:index.php?c=home&a=download)

二、编写具体的文件下载逻辑

项目目录

以本地项目为例,用户需要下载的zip文件,放在当前项目的temp目录下

php实现支持中文的文件下载功能示例

示例

直接上代码,代码中有详细注释

<?php
//接收需要下载的文件名称
if(!isset($_GET['file'])) exit('Filename is empty');
if(empty($_GET['file'])) exit('Filename not valid');
ob_clean();//清除一下缓冲区
//获得文件名称
$filename = basename(urldecode($_GET['file']));
//文件完整路径(这里将真实的文件存放在temp目录下)
$filePath = __DIR__."/temp/".$filename;
//将utf8编码转换成gbk编码,否则,文件中文名称的文件无法打开
$filePath = iconv('UTF-8','gbk',$filePath);
//检查文件是否可读
if(!is_file($filePath) || !is_readable($filePath)) exit('Can not access file '.$filename);
/**
 * 这里应该加上安全验证之类的代码,例如:检测请求来源、验证UA标识等等
 */
//以只读方式打开文件,并强制使用二进制模式
$fileHandle=fopen($filePath,"rb");
if($fileHandle===false){
  exit("Can not open file: $filename");
}
//文件类型是二进制流。设置为utf8编码(支持中文文件名称)
header('Content-type:application/octet-stream; charset=utf-8');
header("Content-Transfer-Encoding: binary");
header("Accept-Ranges: bytes");
//文件大小
header("Content-Length: ".filesize($filePath));
//触发浏览器文件下载功能
header('Content-Disposition:attachment;filename="'.urlencode($filename).'"');
//循环读取文件内容,并输出
while(!feof($fileHandle)) {
  //从文件指针 handle 读取最多 length 个字节(每次输出10k)
  echo fread($fileHandle, 10240);
}
//关闭文件流
fclose($fileHandle);

这里只是做了一个示例(只包括核心功能),为了方便说明直接以GET方式从url中获取用户想要下载的文件名称

注意以下两行代码(为了能够下载中文名称的文件)

$filePath = iconv('UTF-8','gbk',$filePath);
header('Content-type:application/octet-stream; charset=utf-8');

如果用户需要下载的是中文名称的文件。则需要将文件路径转换成gbk编码,否则会出现 文件不存在 之类的错误。header中设置utf8编码,也是同样的道理

下载文件

打开浏览器,访问 http://127.0.0.1/rewrite/尴尬.zip 文件便开始下载了

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
几个学习PHP的网址
Nov 25 PHP
PHP中获取内网用户MAC地址(WINDOWS/linux)的实现代码
Aug 11 PHP
php根据身份证号码计算年龄的实例代码
Jan 18 PHP
初识laravel5
Mar 02 PHP
php获取网页里所有图片并存入数组的方法
Apr 06 PHP
PHP中file_get_contents函数抓取https地址出错的解决方法(两种方法)
Sep 22 PHP
PHP接收json 并将接收数据插入数据库的实现代码
Dec 01 PHP
学习php设计模式 php实现模板方法模式
Dec 08 PHP
PHP二维数组实现去除重复项的方法【保留各个键值】
Dec 21 PHP
PHP PDOStatement::closeCursor讲解
Jan 30 PHP
基于PHP实现短信验证码发送次数限制
Jul 11 PHP
PHP变量的作用范围实例讲解
Dec 22 PHP
利用PHPStorm如何开发Laravel应用详解
Aug 30 #PHP
Laravel 5.5 的自定义验证对象/类示例代码详解
Aug 29 #PHP
PHP单例模式与工厂模式详解
Aug 29 #PHP
PHP迭代与递归实现无限级分类
Aug 28 #PHP
yii2中LinkPager增加总页数和总记录数的实例
Aug 28 #PHP
PHP大文件分割上传 PHP分片上传
Aug 28 #PHP
thinkphp ajaxfileupload实现异步上传图片的示例
Aug 28 #PHP
You might like
现磨咖啡骗局!现磨咖啡=新鲜咖啡?现磨咖啡背后的猫腻你不懂!
2019/03/28 冲泡冲煮
一棵php的类树(支持无限分类)
2006/10/09 PHP
PHP 网页过期时间的控制代码
2009/06/29 PHP
typecho插件编写教程(五):核心代码
2015/05/28 PHP
thinkphp中的url跳转用法分析
2016/07/12 PHP
php中引用&amp;的用法分析【变量引用,函数引用,对象引用】
2016/12/12 PHP
Laravel框架实现redis集群的方法分析
2017/09/14 PHP
javascript globalStorage类代码
2009/06/04 Javascript
JS的replace方法详细介绍
2012/11/09 Javascript
js函数获取html中className所在的内容并去除标签
2013/09/08 Javascript
借助JavaScript脚本判断浏览器Flash Player信息的方法
2014/07/09 Javascript
jquery仅用6行代码实现滑动门效果
2015/09/07 Javascript
完美解决spring websocket自动断开连接再创建引发的问题
2017/03/02 Javascript
jquery拼接ajax 的json和字符串拼接的方法
2017/03/11 Javascript
利用Vue实现移动端图片轮播组件的方法实例
2017/08/23 Javascript
vue+element+Java实现批量删除功能
2019/04/08 Javascript
3分钟读懂移动端rem使用方法(推荐)
2019/05/06 Javascript
js实现贪吃蛇小游戏(加墙)
2020/07/31 Javascript
[38:42]完美世界DOTA2联赛循环赛 Matador vs Forest BO2第二场 11.05
2020/11/05 DOTA
简单介绍Python中的几种数据类型
2016/01/02 Python
Python字符编码判断方法分析
2016/07/01 Python
Python实现复杂对象转JSON的方法示例
2017/06/22 Python
python3 中的字符串(单引号、双引号、三引号)以及字符串与数字的运算
2019/07/18 Python
Python基于pygame实现单机版五子棋对战
2019/12/26 Python
pycharm如何实现跨目录调用文件
2020/02/28 Python
HTML5之SVG 2D入门7—SVG元素的重用与引用
2013/01/30 HTML / CSS
Amara德国:家居饰品、设计师品牌和豪华礼品
2019/05/20 全球购物
工商企业管理应届生求职信
2013/11/03 职场文书
音乐幼师求职信
2014/07/09 职场文书
党员批评与自我批评发言
2014/10/02 职场文书
企业法人代表授权委托书
2014/10/02 职场文书
2014年办公室人员工作总结
2014/12/09 职场文书
2015年保管员工作总结
2015/04/30 职场文书
教学质量月活动总结
2015/05/11 职场文书
2016年“我们的节日·中秋节”活动总结
2016/04/05 职场文书
浅谈Python魔法方法
2021/06/28 Java/Android