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冒泡排序算法的深入理解
Jun 09 PHP
PHP按行读取文件时删除换行符的3种方法
May 04 PHP
IIS下PHP的三种配置方式对比
Nov 20 PHP
php bootstrap实现简单登录
Mar 08 PHP
php实现在新浪云中使用imagick生成缩略图并上传的方法
Sep 26 PHP
浅谈Yii乐观锁的使用及原理
Jul 25 PHP
PHP观察者模式原理与简单实现方法示例
Aug 25 PHP
php实现生成带二维码图片并强制下载功能
Feb 24 PHP
Laravel框架自定义验证过程实例分析
Feb 01 PHP
详解php中curl返回false的解决办法
Mar 18 PHP
PHP面向对象类型约束用法分析
Jun 12 PHP
漂亮的thinkphp 跳转页封装示例
Oct 16 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
PHP extract 将数组拆分成多个变量的函数
2010/06/30 PHP
php常用文件操作函数汇总
2014/11/22 PHP
Laravel 5.4.36中session没有保存成功问题的解决
2018/02/19 PHP
autoPlay 基于jquery的图片自动播放效果
2011/12/07 Javascript
JavaScript高级程序设计(第3版)学习笔记6 初识js对象
2012/10/11 Javascript
输入自动提示搜索提示功能的使用说明:sugggestion.txt
2013/09/02 Javascript
jquery动态改变onclick属性导致失效的问题解决方法
2013/12/04 Javascript
Javascript基础教程之定义和调用函数
2015/01/18 Javascript
jQuery实现的数值范围range2dslider选取插件特效多款代码分享
2015/08/27 Javascript
浅析javascript中的事件代理
2015/11/06 Javascript
canvas实现手机端用来上传用户头像的代码
2016/10/20 Javascript
JS验证字符串功能
2017/02/22 Javascript
jquery仿苹果的时间/日期选择效果
2017/03/08 Javascript
基于JavaScript实现活动倒计时效果
2017/04/20 Javascript
用原生JS实现简单的多选框功能
2017/06/12 Javascript
详解基于webpack2.x的vue2.x的多页面站点
2017/08/21 Javascript
nodejs中Express与Koa2对比分析
2018/02/06 NodeJs
JS获取子节点、父节点和兄弟节点的方法实例总结
2018/07/06 Javascript
webpack 从指定入口文件中提取公共文件的方法
2018/11/13 Javascript
vue实现动态显示与隐藏底部导航的方法分析
2019/02/11 Javascript
js实现弹幕墙效果
2020/12/10 Javascript
[09:37]2018DOTA2国际邀请赛寻真——不懈追梦的Team Serenity
2018/08/13 DOTA
python开发之函数定义实例分析
2015/11/12 Python
Python错误处理操作示例
2018/07/18 Python
Python实例方法、类方法、静态方法的区别与作用详解
2019/03/25 Python
Python使用Pandas库实现MySQL数据库的读写
2019/07/06 Python
详解python 中in 的 用法
2019/12/12 Python
python enumerate内置函数用法总结
2020/01/07 Python
Python virtualenv虚拟环境实现过程解析
2020/04/18 Python
python 窃取摄像头照片的实现示例
2021/01/08 Python
世界上最全面的汽车零部件和配件集合:JC Whitney
2016/09/04 全球购物
卖房协议书
2014/04/11 职场文书
民事授权委托书范文
2014/08/02 职场文书
2015年社区党建工作汇报材料
2015/06/25 职场文书
从贫穷到富有,是知识技能和学习力的差别
2019/08/20 职场文书
react antd实现动态增减表单
2021/06/03 Javascript