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 chr() ord()中文截取乱码问题解决方法
Sep 08 PHP
一步一步学习PHP(8) php 数组
Mar 05 PHP
php smarty函数扩展
Mar 15 PHP
PHP与MySQL开发的8个技巧小结
Dec 17 PHP
PHP及Zend Engine的线程安全模型分析
Nov 10 PHP
PHP中常用的字符串格式化函数总结
Nov 19 PHP
windows下apache搭建php开发环境
Aug 27 PHP
Yii2.0高级框架数据库增删改查的一些操作
Nov 16 PHP
PHP与Java对比学习日期时间函数
Jul 03 PHP
php获取客户端IP及URL的方法示例
Feb 03 PHP
ThinkPHP中获取指定日期后工作日的具体日期方法
Oct 14 PHP
如何在Laravel5.8中正确地应用Repository设计模式
Nov 26 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
使用Smarty 获取当前日期时间和格式化日期时间的方法详解
2013/06/18 PHP
C# WinForm中实现快捷键自定义设置实例
2015/01/23 PHP
php导入模块文件分享
2015/03/17 PHP
jQuery AJAX实现调用页面后台方法和web服务定义的方法分享
2012/03/01 Javascript
JS常用正则表达式总结
2013/11/12 Javascript
js解决弹窗问题实现班级跳转DIV示例
2014/01/06 Javascript
手写的一个兼容各种浏览器的javascript getStyle函数(获取元素的样式)
2014/06/06 Javascript
使用HTML+CSS+JS制作简单的网页菜单界面
2015/07/27 Javascript
js表单处理中单选、多选、选择框值的获取及表单的序列化
2016/03/08 Javascript
jQuery插件EasyUI设置datagrid的checkbox为禁用状态的方法
2016/08/05 Javascript
Vue+Element使用富文本编辑器的示例代码
2017/08/14 Javascript
vue的传参方式汇总和router使用技巧
2018/05/22 Javascript
vue  自定义组件实现通讯录功能
2018/09/30 Javascript
JS实现获取当前所在周的周六、周日示例分析
2019/05/11 Javascript
详解新手使用vue-router传参时注意事项
2019/06/06 Javascript
Layui数据表格之单元格编辑方式
2019/10/26 Javascript
JavaScript观察者模式原理与用法实例详解
2020/03/10 Javascript
python二分法实现实例
2013/11/21 Python
Python实现随机生成有效手机号码及身份证功能示例
2017/06/05 Python
详解Python中的分组函数groupby和itertools)
2018/07/11 Python
python nmap实现端口扫描器教程
2020/05/28 Python
Numpy一维线性插值函数的用法
2020/04/22 Python
pycharm 代码自动补全的实现方法(图文)
2020/09/18 Python
python+appium+yaml移动端自动化测试框架实现详解
2020/11/24 Python
纽约21世纪百货官网:Century 21
2016/08/27 全球购物
ziaja齐叶雅官方海外旗舰店:来自波兰的天然护肤品牌
2017/01/02 全球购物
旅游管理专业生自荐信范文
2014/01/02 职场文书
《我的伯父鲁迅先生》教学反思
2014/02/12 职场文书
聚美优品广告词改编
2014/03/14 职场文书
一体化教学实施方案
2014/05/10 职场文书
热门专业求职信
2014/05/24 职场文书
经典团队口号大全
2014/06/21 职场文书
领导干部群众路线个人对照检查材料思想汇报
2014/09/30 职场文书
2014年社区党建工作汇报材料
2014/11/02 职场文书
2014年护理工作总结范文
2014/11/14 职场文书
python Django框架快速入门教程(后台管理)
2021/07/21 Python