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 相关文章推荐
文章推荐系统(二)
Oct 09 PHP
下载文件的点击数回填
Oct 09 PHP
IStream与TStream之间的相互转换
Aug 01 PHP
php inc文件使用的风险和注意事项
Nov 12 PHP
php获取文件内容最后一行示例
Jan 09 PHP
ThinkPHP的Widget扩展实例
Jun 19 PHP
Yii控制器中filter过滤器用法分析
Jul 15 PHP
php简单中奖算法(实例)
Aug 15 PHP
php利用云片网实现短信验证码功能的示例代码
Nov 18 PHP
浅谈Laravel中的三种中间件的作用
Oct 13 PHP
基于PHP的登录和注册的功能的实现
Aug 06 PHP
基于PHP实现发微博动态代码实例
Dec 11 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 如何获取数组第一个值
2013/08/06 PHP
php使用exec shell命令注入的方法讲解
2013/11/12 PHP
PHP+MySQL统计该库中每个表的记录数并按递减顺序排列的方法
2016/02/15 PHP
Yii中的relations数据关联查询及统计功能用法详解
2016/07/14 PHP
PHP的openssl加密扩展使用小结(推荐)
2016/07/18 PHP
Yii2.0使用阿里云OSS的SDK上传图片、下载、删除图片示例
2017/09/20 PHP
推荐一些非常不错的javascript学习资源站点
2007/08/29 Javascript
基于jquery的超简单上下翻
2010/04/20 Javascript
前端开发的开始---基于面向对象的Ajax类
2010/09/17 Javascript
使用Jquery搭建最佳用户体验的登录页面之记住密码自动登录功能(含后台代码)
2011/07/10 Javascript
Jquery插件之打造自定义的select标签
2011/11/30 Javascript
jquery 倒计时效果实现秒杀思路
2013/09/11 Javascript
各种页面定时跳转(倒计时跳转)代码总结
2013/10/24 Javascript
JS+CSS实现简易实用的滑动门菜单效果
2015/09/18 Javascript
javascript图片切换综合实例(循环切换、顺序切换)
2016/01/13 Javascript
JavaScript:Array类型全面解析
2016/05/19 Javascript
KnockoutJS 3.X API 第四章之数据控制流component绑定
2016/10/10 Javascript
JS定时器实现数值从0到10来回变化
2016/12/09 Javascript
Jquery Easyui菜单组件Menu使用详解(15)
2016/12/18 Javascript
JS获取浮动(float)元素的style.left值为空的快速解决办法
2017/02/19 Javascript
微信小程序实现左右联动的实战记录
2018/07/05 Javascript
比较详细Python正则表达式操作指南(re使用)
2008/09/06 Python
深入学习python多线程与GIL
2019/08/26 Python
python 实现保存最新的三份文件,其余的都删掉
2019/12/22 Python
详解Python3 中的字符串格式化语法
2020/01/15 Python
Python中实现输入超时及如何通过变量获取变量名
2020/01/18 Python
什么是事务?事务有哪些性质?
2012/03/11 面试题
2014年国庆节演讲稿精选范文1500字
2014/09/25 职场文书
销售经理工作失职检讨书
2014/10/24 职场文书
2015年行政人事工作总结
2015/05/21 职场文书
开天辟地观后感
2015/06/09 职场文书
保护地球的宣传语
2015/07/13 职场文书
诉讼和解协议书
2016/03/23 职场文书
读《儒林外史》有感:少一些功利,多一些真诚
2020/01/19 职场文书
《吸血鬼:避世 血猎》官宣4.27发售 系列首款大逃杀
2022/04/03 其他游戏
python读取并查看npz/npy文件数据以及数据显示方法
2022/04/14 Python