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 IP及IP段进行访问限制的代码
Dec 17 PHP
php数据结构 算法(PHP描述) 简单选择排序 simple selection sort
Aug 09 PHP
PHP中替换换行符的几种方法小结
Oct 15 PHP
ThinkPHP的I方法使用详解
Jun 18 PHP
php中解析带中文字符的url函数分享
Jan 20 PHP
php递归法读取目录及文件的方法
Jan 30 PHP
php中文验证码实现方法
Jun 18 PHP
yii2使用GridView实现数据全选及批量删除按钮示例
Mar 01 PHP
详解php实现页面静态化原理
Jun 21 PHP
针对thinkPHP5框架存储过程bug重写的存储过程扩展类完整实例
Jun 16 PHP
PHP验证类的封装与使用方法详解
Jan 10 PHP
PHP Web表单生成器案例分析
Jun 02 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
一个数据采集类
2007/02/14 PHP
php HTML无刷新提交表单
2016/04/05 PHP
Yii核心验证器api详解
2016/11/23 PHP
JSON 客户端和服务器端的格式转换
2009/08/27 Javascript
JS 用6N±1法求素数 实例教程
2009/10/20 Javascript
Jquery实现点击切换图片并隐藏显示内容(2种方法实现)
2013/04/11 Javascript
JS如何将UTC格式时间转本地格式
2013/09/04 Javascript
jQuery获取上传文件的名称的正则表达式
2015/05/21 Javascript
javascript实现很浪漫的气泡冒出特效
2020/09/05 Javascript
JavaScript中有关一个数组中最大值和最小值及它们的下表的输出的解决办法
2016/07/01 Javascript
vue.js单页面应用实例的简单实现
2017/04/10 Javascript
微信小程序新增的拖动组件movable-view使用教程
2017/05/20 Javascript
总结js中的一些兼容性易错的问题
2017/12/18 Javascript
微信小程序实现循环动画效果
2018/07/16 Javascript
Vue路由切换页面不更新问题解决方案
2020/07/10 Javascript
解决iview table组件里的 固定列 表格不自适应的问题
2020/11/13 Javascript
Vue 使用iframe引用html页面实现vue和html页面方法的调用操作
2020/11/16 Javascript
JavaScript实现雪花飘落效果
2020/12/27 Javascript
Python strip lstrip rstrip使用方法
2008/09/06 Python
python操作CouchDB的方法
2014/10/08 Python
Python中获取网页状态码的两个方法
2014/11/03 Python
50行Python代码实现人脸检测功能
2018/01/23 Python
python取代netcat过程分析
2018/02/10 Python
利用pandas读取中文数据集的方法
2018/07/25 Python
python获取array中指定元素的示例
2019/11/26 Python
纯CSS3实现圆角效果(含IE兼容解决方法)
2014/05/07 HTML / CSS
HTML5新增元素如何兼容旧浏览器有哪些方法
2014/05/09 HTML / CSS
5 个强大的HTML5 API 函数推荐
2014/11/19 HTML / CSS
Html5新增标签有哪些
2017/04/13 HTML / CSS
Canvas在超级玛丽游戏中的应用详解
2021/02/06 HTML / CSS
澳大利亚儿童和婴儿产品在线商店:Lime Tree Kids
2017/10/05 全球购物
What's the difference between an interface and abstract class? (接口与抽象类有什么区别)
2012/10/29 面试题
解释一下钝化(Swap out)
2016/12/26 面试题
心理咨询承诺书
2014/05/20 职场文书
诚实守信演讲稿
2014/09/01 职场文书
个人查摆剖析材料
2014/10/04 职场文书