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 删除记录实现代码
Mar 12 PHP
Windows PHP5和Apache的安装与配置
Jun 08 PHP
php中自定义函数dump查看数组信息类似var_dump
Jan 27 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(八)
Jun 23 PHP
php实现的mongodb操作类
May 28 PHP
PHP中addslashes()和stripslashes()实现字符串转义和还原用法实例
Jan 07 PHP
浅析php静态方法与非静态方法的用法区别
May 17 PHP
Yii2组件之多图上传插件FileInput的详细使用教程
Jun 20 PHP
PHP空值检测函数与方法汇总
Nov 19 PHP
php框架CodeIgniter使用redis的方法分析
Apr 13 PHP
php设计模式之单例模式用法经典示例分析
Sep 20 PHP
YII2框架中behavior行为的理解与使用方法示例
Mar 13 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中 ob_start等函数截取标准输出的方法
2015/06/22 PHP
PHP里面把16进制的图片数据显示在html的img标签上(实现方法)
2017/05/02 PHP
Nigma vs Liquid BO3 第二场2.14
2021/03/10 DOTA
ASP.NET jQuery 实例1(在TextBox里面创建一个默认提示)
2012/01/13 Javascript
来自国外的30个基于jquery的Web下拉菜单
2012/06/22 Javascript
animate动画示例(泪奔的小孩)及stop和delay的使用
2013/05/06 Javascript
关于include标签导致js路径找不到的问题分析及解决
2013/07/09 Javascript
javascript中怎么做对象的类型判断
2013/11/11 Javascript
js简单的弹出框有关闭按钮
2014/05/05 Javascript
JavaScript动态改变HTML页面元素例如添加或删除
2014/08/10 Javascript
jQuery中data()方法用法实例
2014/12/27 Javascript
一张Web前端的思维导图分享
2015/07/03 Javascript
js实现交通灯效果
2017/01/13 Javascript
超全面的vue.js使用总结
2017/02/12 Javascript
AngularJS实现单一页面内设置跳转路由的方法
2017/06/28 Javascript
JavaScript中的E-mail 地址格式验证
2018/03/28 Javascript
layui 图片上传+表单提交+ Spring MVC的实例
2019/09/21 Javascript
JS原形与原型链深入详解
2020/05/09 Javascript
Python3实现连接SQLite数据库的方法
2014/08/23 Python
详解在Python中处理异常的教程
2015/05/24 Python
Python如何判断数独是否合法
2016/09/08 Python
python实现杨辉三角思路
2017/07/14 Python
Python爬虫之xlml解析库(全面了解)
2017/08/08 Python
解决pycharm运行程序出现卡住scanning files to index索引的问题
2019/06/27 Python
python经典趣味24点游戏程序设计
2019/07/26 Python
巴基斯坦电子产品购物网站:Home Shopping
2017/09/14 全球购物
Python面试题:Python是如何进行内存管理的
2014/08/04 面试题
PHP引擎php.ini参数优化深入讲解
2021/03/24 PHP
优秀学生获奖感言
2014/02/15 职场文书
工厂仓管员岗位职责范本
2014/07/17 职场文书
商铺门前三包责任书
2014/07/25 职场文书
个人作风建设总结
2014/10/23 职场文书
小学教师求职信范文
2015/03/20 职场文书
node快速搭建后台的实现步骤
2022/02/18 NodeJs
Golang流模式之grpc的四种数据流
2022/04/13 Golang
Redis基本数据类型Zset有序集合常用操作
2022/06/01 Redis