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小偷的核心程序
Apr 09 PHP
php中iconv函数使用方法
May 24 PHP
理解php原理的opcodes(操作码)
Oct 26 PHP
php 传值赋值与引用赋值的区别
Dec 29 PHP
Apache下禁止php文件被直接访问的解决方案
Apr 25 PHP
Memcached常用命令以及使用说明详解
Jun 27 PHP
thinkphp的URL路由规则与配置实例
Nov 26 PHP
腾讯微博提示missing parameter errorcode 102 错误的解决方法
Dec 22 PHP
php传值赋值和传地址赋值用法实例分析
Jun 20 PHP
PHP与Java对比学习日期时间函数
Jul 03 PHP
windows环境下使用Composer安装ThinkPHP5
May 18 PHP
CI框架实现创建自定义类库的方法
Dec 25 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之第七天
2006/10/09 PHP
深入php函数file_get_contents超时处理的方法详解
2013/06/03 PHP
PHP下载文件的函数实例代码
2016/05/18 PHP
Laravel定时任务的每秒执行代码
2019/10/22 PHP
Nigma vs AM BO3 第二场2.13
2021/03/10 DOTA
jQuery Tools Dateinput使用介绍
2012/07/14 Javascript
使用JSLint提高JS代码质量方法分享
2013/12/16 Javascript
css如何让浮动元素水平居中
2015/08/07 Javascript
JS实现颜色梯度与渐变效果完整实例
2016/12/30 Javascript
jQuery编写网页版2048小游戏
2017/01/06 Javascript
loading动画特效小结
2017/01/22 Javascript
js获取一组日期中最近连续的天数
2017/05/25 Javascript
Angular整合zTree的示例代码
2018/01/24 Javascript
微信小程序搭建(mpvue+mpvue-weui+fly.js)的详细步骤
2018/09/18 Javascript
jquery操作checkbox的常用方法总结【附测试源码下载】
2019/06/10 jQuery
JS使用正则表达式实现常用的表单验证功能分析
2020/04/30 Javascript
[06:10]6.81新信使新套装!给你一个炫酷的DOTA2
2014/05/06 DOTA
对于Python中RawString的理解介绍
2016/07/07 Python
Python使用pip安装报错:is not a supported wheel on this platform的解决方法
2018/01/23 Python
人脸识别经典算法一 特征脸方法(Eigenface)
2018/03/13 Python
Python 忽略warning的输出方法
2018/10/18 Python
深入理解Django-Signals信号量
2019/02/19 Python
python requests模拟登陆github的实现方法
2019/12/26 Python
Spring http服务远程调用实现过程解析
2020/06/11 Python
GAP阿联酋官网:GAP UAE
2017/11/30 全球购物
英国最大的正宗复古足球衫制造商和零售商:TOFFS
2018/06/21 全球购物
精细化工应届生求职信
2013/11/17 职场文书
餐厅感恩节活动策划方案
2014/10/11 职场文书
外国人来华邀请函
2015/01/31 职场文书
内勤岗位职责
2015/02/10 职场文书
2015秋季幼儿园开学通知
2015/07/16 职场文书
三十年同学聚会感言
2015/07/30 职场文书
有关浪费资源的建议书
2015/09/14 职场文书
2021-4-5课程——SQL Server查询【3】
2021/04/05 SQL Server
BCL经典机 SONY ICF-5900W电路分析
2022/04/24 无线电
Java 多线程协作作业之信号同步
2022/05/11 Java/Android