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出现Cannot modify header information问题的解决方法大全
Apr 09 PHP
PHP写MySQL数据 实现代码
Jun 15 PHP
PHP基础学习小结
Apr 17 PHP
基于header的一些常用指令详解
Jun 06 PHP
PHP递归删除目录几个代码实例
Apr 21 PHP
php常用文件操作函数汇总
Nov 22 PHP
php从memcache读取数据再批量写入mysql的方法
Dec 29 PHP
浅析iis7.5安装配置php环境
May 10 PHP
php根据生日计算年龄的方法
Jul 13 PHP
php商品对比功能代码分享
Sep 24 PHP
WordPress中用于创建以及获取侧边栏的PHP函数讲解
Dec 29 PHP
PHP入门教程之PHP操作MySQL的方法分析
Sep 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访问MYSQL数据库封装类(附函数说明)
2010/12/04 PHP
PHP 万年历实现代码
2012/10/18 PHP
解析PHP跨站刷票的实现代码
2013/06/18 PHP
php文件上传类完整实例
2016/05/14 PHP
php支付宝在线支付接口开发教程
2016/09/19 PHP
PHP中include()与require()的区别说明
2017/02/14 PHP
微信公众号开发之通过接口删除菜单
2017/02/20 PHP
PHP面向对象程序设计之多态性的应用示例
2018/12/19 PHP
javascript json 新手入门文档
2009/12/03 Javascript
原生Js与jquery的多组处理, 仅展开一个区块的折叠效果
2011/01/09 Javascript
NodeJS框架Express的模板视图机制分析
2011/07/19 NodeJs
jquery写个checkbox——类似邮箱全选功能
2013/03/19 Javascript
原生JS绑定滑轮滚动事件兼容常见浏览器
2014/06/30 Javascript
javascript面向对象之this关键词用法分析
2015/01/13 Javascript
nodejs爬虫抓取数据之编码问题
2015/07/03 NodeJs
动态加载js、css的实例代码
2016/05/26 Javascript
javascript 中的console.log和弹出窗口alert
2016/08/30 Javascript
微信小程序地图导航功能实现完整源代码附效果图(推荐)
2019/04/28 Javascript
关于vue-cli3打包代码后白屏的解决方案
2020/09/02 Javascript
如何在vue-cli中使用css-loader实现css module
2021/01/07 Vue.js
[02:20]DOTA2中文配音宣传片
2013/05/22 DOTA
python检测是文件还是目录的方法
2015/07/03 Python
Pycharm在创建py文件时,自动添加文件头注释的实例
2018/05/07 Python
使用Python OpenCV为CNN增加图像样本的实现
2019/06/10 Python
Django上使用数据可视化利器Bokeh解析
2019/07/31 Python
美国奢侈品在线团购网站:Gilt City
2017/11/16 全球购物
百思买加拿大:Best Buy Canada
2018/03/20 全球购物
九年级科学教学反思
2014/01/29 职场文书
制作部班长职位说明书
2014/02/26 职场文书
机械设计及其自动化专业求职信
2014/06/09 职场文书
民间借贷协议书范本
2014/10/01 职场文书
公司授权委托书格式范文
2014/10/02 职场文书
MySQL 8.0 Online DDL快速加列的相关总结
2021/06/02 MySQL
TypeScript 使用 Tuple Union 声明函数重载
2022/04/07 Javascript
浅析JavaScript中的变量提升
2022/06/01 Javascript
Python创建SQL数据库流程逐步讲解
2022/09/23 Python