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 和 MySQL 开发的 8 个技巧
Jan 02 PHP
PHP 数组遍历顺序理解
Sep 09 PHP
PHP中的float类型使用说明
Jul 27 PHP
Codeigniter框架的更新事务(transaction)BUG及解决方法
Jul 25 PHP
php生成图片缩略图的方法
Apr 07 PHP
Smarty中的注释和截断功能介绍
Apr 09 PHP
给WordPress的编辑后台添加提示框的代码实例分享
Dec 25 PHP
Zend Framework教程之模型Model用法简单实例
Mar 04 PHP
php实现学生管理系统
Mar 21 PHP
thinkphp5 加载静态资源路径与常量的方法
Dec 24 PHP
PHP receiveMail实现收邮件功能
Apr 25 PHP
Laravel5.7框架安装与使用学习笔记图文详解
Apr 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
完美实现wordpress禁止文章修订和自动保存的方法
2014/11/03 PHP
支持中文的PHP按字符串长度分割成数组代码
2015/05/17 PHP
示例详解Laravel重置密码代码重构
2016/08/10 PHP
基于php(Thinkphp)+jquery 实现ajax多选反选不选删除数据功能
2017/02/24 PHP
菜鸟javascript基础资料整理3 正则
2010/12/06 Javascript
js中利用tagname和id获取元素的方法
2016/01/03 Javascript
7个jQuery最佳实践
2016/01/12 Javascript
AngularJS基础 ng-list 指令详解及示例代码
2016/08/02 Javascript
用JS动态设置CSS样式常见方法小结(推荐)
2016/11/10 Javascript
jquery.multiselect多选下拉框实现代码
2016/11/11 Javascript
基于Bootstrap的Java开发问题汇总(Spring MVC)
2017/01/15 Javascript
JS控制鼠标拒绝点击某一按钮的实例
2017/12/29 Javascript
vue组件(全局,局部,动态加载组件)
2018/09/02 Javascript
js自定义input文件上传样式
2018/10/26 Javascript
vue router动态路由设置参数可选问题
2019/08/21 Javascript
js前端如何写一个精确的倒计时代码
2019/10/25 Javascript
vue实现设置载入动画和初始化页面动画效果
2019/10/28 Javascript
微信小程序仿抖音视频之整屏上下切换功能的实现代码
2020/05/24 Javascript
vue和H5 draggable实现拖拽并替换效果
2020/07/29 Javascript
Python实现模拟时钟代码推荐
2015/11/08 Python
python实现随机漫步算法
2018/08/27 Python
python查看模块,对象的函数方法
2018/10/16 Python
python使用for循环计算0-100的整数的和方法
2019/02/01 Python
深入解析python中的实例方法、类方法和静态方法
2019/03/11 Python
解决Python3用PIL的ImageFont输出中文乱码的问题
2019/08/22 Python
python selenium循环登陆网站的实现
2019/11/04 Python
Tensorflow累加的实现案例
2020/02/05 Python
Python+OpenCV图像处理——打印图片属性、设置存储路径、调用摄像头
2020/10/22 Python
北京麒麟网信息技术有限公司网络游戏测试面试题
2013/09/28 面试题
法律进社区实施方案
2014/03/21 职场文书
学校安全工作汇报材料
2014/08/16 职场文书
同学会感言
2015/07/30 职场文书
初中军训感言
2015/08/01 职场文书
MySQL官方导出工具mysqlpump的使用
2021/05/21 MySQL
52条SQL语句教你性能优化
2021/05/25 MySQL
pytorch finetuning 自己的图片进行训练操作
2021/06/05 Python