php文件下载方法问题

求教大牛指教...昨天需要实现一个网站文件下载功能,我用的之前用过的下载方法,结果每次下载下来都打不开,显示文件已损毁,但是这段代码在本地可以正常下载,我试过很多次了,是不是下载服务器上的文件和本地有什么不同?
代码是之前网上找的,没仔细研究过.

/*
 * @param  [type] $url   图片地址
 * @param  [type] $title 图片标题
 * @return [type]    [description]
 */
public function downloadCert($url,$title)
{
    if(empty($url)){
        return false;
    }
    //获取文件名称及后缀名
    $basename = pathinfo($url);
    //如果有文件名字则使用,没有则使用默认名称
    if(empty($title)){
        $title = $basename['basename'];
    }else{
        $title = $title.'.'.$basename['extension'];
    }
    $url = substr($url, stripos($url, '/')+1);
    $url = PUBLIC_PATH . $url;  
    if(!file_exists($url)){
       exit;
    }

    $file=fopen($url,"r");
    if (!$file) {
        $this->error('此文件不存在');
    }
    header("Content-Type: application/octet-stream");
    header("Accept-Ranges: bytes");
    header("Accept-Length: ".filesize($url));
    header("Content-Disposition: attachment; filename=". $title);
    echo fread($file,filesize($url));
    fclose($file);

}

image.png

然后我又从网上找了一段代码,可以正常下载并打开.

/*
 * 下载问题附件
 * @param string $url 附件地址
 * @param string $title 标题
 * @return
 */
public function downloadFile($url)
{
        //接收需要下载的文件名称
        ob_clean();//清除一下缓冲区
        //获得文件名称
        $filename = basename(urldecode($url));
        //文件完整路径
        $filePath = ROOT_PATH . 'public' . $url;
        //将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);

}

这一段代码可以下载服务器上的文件,
请问他俩的区别在哪,是因为第二段多了一个urlencode转码的原因吗? 
我是用的get方式传文件地址 
阅读 1.8k
2 个回答

fopen 的第二个参数。r 表示读,b 表示二进制处理。
clipboard.png

当未指定http编码头,文件下载时,编码自动填充为服务器编码。
本地编码与服务器编码不一致,文件无法识别也就打开。
你可以试一下将上次的图片转换一下编码,或者用专业的图像处理文件打开,就清楚了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题