文件下载(包含中文、超过2.5G大文件、IE下载乱码解决)

public function downLoad()
    {   
        // 时间调整,下载大文件
        ini_set('max_execution_time','3600');
        // 传的参数,最终目的为了找到要下载文件的路径
        $id            = input('file_path_name');
        $name          = input('name');
        // 下载所需的header头
        header("Content-type:text/html;charset=utf-8");
        // 查询数据库表获取文件所在路径
        $info    = $this->mod->getInfo($id);
        // 数据库中若没有,返回错误
        if(empty($info)){
            return json(error('参数错误'));
        }
        // 判断文件是否有权限下载(审批通过)
        if($info['approve_status'] != 1 ){
            return json(error('未审批或审批不通过,暂时无法下载'));
        }
        // 拼接路径,获取下载地址
        $file_path                 = 'E:\produce\standardversion'.$info['down_path'];
        // 获取文件名
        $file_name                 = trim(strrchr($file_path, '/'),'/');
        // 文件路径中有可能有中文,直接下载有可能出错,转换后下载
        $file_path = iconv('utf-8', 'gbk', $file_path);
        //首先要判断给定的文件存在与否
        if(!file_exists($file_path)){
            return json(error('没有该文件!'));
        }
        // 大于2G的文件filesize函数获取文件大小错误(不准确或为负数),造成下载不了。特使用sprintf函数,转换后能获取
        // 正确的文件大小。(PHP7没有此问题,filesize函数能正确获取文件大小)
        $file_size                 = sprintf("%u",filesize($file_path));
        // 下载相关设置
        set_time_limit(0);
        ini_set('max_execution_time', '0');
        ini_set('memory_limit','-1');
        // IE中下载中文乱码,使用urlencode函数转换
        $file_name = urlencode($file_name);
        //下载文件需要用到的头
        header("content-type:application/octet-stream");
        header("Accept-Ranges:bytes");
        header("Content-Length:".$file_size);
        header("content-disposition:attachment;filename=".$file_name);
        header("Content-Transfer-Encoding:binary");
        header("Content-Description:File Transfer");
        // 每次读取数据的大小
        $buffer                    = 8192;
        // 打开句柄
        $fp                        = fopen($file_path,"rb");
        $file_count                = 0;
        // 清除缓存,避免干扰
        ob_clean();
        flush();
        //向浏览器返回数据(循环读取,每次读取$buffer大小,)
        while(!feof($fp) && $file_count<$file_size){
            set_time_limit(0);
            $file_con              =  fread($fp,$buffer);
            $file_count            += $buffer;
            echo $file_con;
            ob_flush(); // 刷新PHP缓冲区到Web服务器
            flush(); // 刷新Web服务器缓冲区到浏览器
        }
        // 关闭句柄
        fclose($fp);
        // 下载完成后写入下载log里(自定义封装逻辑)
        $this->mod_log->add([
            'log_id'           => $id,
            'name'             => $name,
            'operation'        => '下载',
            'produce_model_number' => $info['produce_model_number'],
            'version_name'     => $info['version_name'],
            'version_remark'   => $info['version_remark'],
            'down_path'        => $info['down_path'],
            'four_type'        => $info['four_type'],
            'type'             => $info['type'],
            'version_or_book'  => 'version',
            'time'             => time()
        ]);
        // 返回完成ok
        return json(ok());
    }
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值