//下载,记录到表 public function download(){ // $res=M('document')->where(['id'=>$id])->find(); $path=$res['address']; $filename=$res['name']; // $fname = urldecode($fname); // $fpath = $_SERVER['DOCUMENT_ROOT'].'/Uploads/Attachement/'; //避免中文文件名出现检测不到文件名的情况,进行转码utf-8->gbk $filename=iconv('utf-8', 'gb2312', $filename)?:$filename; $path=iconv('utf-8', 'gb2312', $path)?:$path; // $path=$fpath.$filename; if(!file_exists($path)){//检测文件是否存在 header("Content-type:text/html;charset=utf-8"); // echo "文件不存在!"; echo "抱歉,文件已经不存在,请联络客服处理! <a href='javascript:window.history.go(-1)' style='padding:3px 8px;background:#ffb400;color:#fff;border-radius:3px;text-decoration: none;'>返回</a>"; die(); } $fp=fopen($path,'r');//只读方式打开 $filesize=filesize($path);//文件大小 // set_time_limit(0); // ini_set('memory_limit', '5M'); header("Content-type:text/html;charset=utf-8"); //返回的文件(流形式) header("Content-type: application/octet-stream"); // header("Content-type: application/msword"); //按照字节大小返回 header("Accept-Ranges: bytes"); //返回文件大小 header("Accept-Length: $filesize"); //这里客户端的弹出对话框,对应的文件名 header("Content-Disposition: attachment; filename=".$filename); if (preg_match('/MSIE/', $_SERVER['HTTP_USER_AGENT'])) { //for IE header('Content-Disposition: attachment; filename="' . rawurlencode($filename) . '"'); } else { header('Content-Disposition: attachment; filename="' . $filename . '"'); } ob_clean(); flush(); //fread()下载word,文件不完整,乱码 // //设置分流 // $buffer=1024; // //来个文件字节计数器 // $count=0; // while(!feof($fp)&&($filesize>$count)){ // $data=fread($fp,$buffer); // $count+=$data;//计数 // echo $data;//传数据给浏览器端 // // } while(!feof($fp)) { echo fgets($fp, 4096); } fclose($fp); }
以下代码未做测试https://www.cnblogs.com/liuzhaobo1999 皮皮蛋 2017/07/10 22:08:08 <?php // 暂不支持断点续传 // $url = 'http://www.mytest.com/debian.iso '; 不知道为何获取本地文件大小为0 $url = 'http://192.168.8.93/download/vm-672/18/0.vmdk'; $file = basename($url); $header = get_headers($url, 1); $size = $header['Content-Length']; $fp = fopen($url, 'rb'); if ($fp === false) exit('文件不存在或打开失败'); header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="'.$file.'"'); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header('Content-Length: ' . $size); ob_clean(); ob_end_flush(); set_time_limit(0); $chunkSize = 1024 * 1024; while (!feof($fp)) { $buffer = fread($fp, $chunkSize); echo $buffer; ob_flush(); flush(); } fclose($fp); exit; 2017/7/10 22:19:53 我 2017/7/10 22:19:53 皮皮蛋 2017/07/10 22:19:53 function downloadBagFile($filePath) { //设置文件最长执行时间和内存 set_time_limit ( 0 ); ini_set ( 'memory_limit', '1024M' ); //检测文件是否存在 if (! is_file ( $filePath )) { die ( "<b>404 File not found!</b>" ); } $filename = basename ( $filePath ); //获取文件名字 //开始写输出头信息 header ( "Cache-Control: public" ); //设置输出浏览器格式 header ( "Content-Type: application/octet-stream" ); header ( "Content-Disposition: attachment; filename=" . $filename ); header ( "Content-Transfer-Encoding: binary" ); header ( "Accept-Ranges: bytes" ); $size = filesize ( $filePath ); $range=0; //如果有$_SERVER['HTTP_RANGE']参数 if (isset ( $_SERVER ['HTTP_RANGE'] )) { /*Range头域 Range头域可以请求实体的一个或者多个子范围。 例如, 表示头500个字节:bytes=0-499 表示第二个500字节:bytes=500-999 表示最后500个字节:bytes=-500 表示500字节以后的范围:bytes=500- 第一个和最后一个字节:bytes=0-0,-1 同时指定几个范围:bytes=500-600,601-999 但是服务器可以忽略此请求头,如果无条件GET包含Range请求头,响应会以状态码206(PartialContent)返回而不是以200 (OK). */ // 断点后再次连接 $_SERVER['HTTP_RANGE'] 的值 bytes=4390912- list ( $a, $range ) = explode ( "=", $_SERVER ['HTTP_RANGE'] ); //if yes, download missing part $size2 = $size - 1; //文件总字节数 $new_length = $size2 - $range; //获取下次下载的长度 header ( "HTTP/1.1 206 Partial Content" ); header ( "Content-Length: {$new_length}" ); //输入总长 header ( "Content-Range: bytes {$range}-{$size2}/{$size}" ); //Content-Range: bytes 4908618-4988927/4988928 95%的时候 } else { //第一次连接 $size2 = $size - 1; header ( "Content-Range: bytes 0-{$size2}/{$size}" ); //Content-Range: bytes 0-4988927/4988928 header ( "Content-Length: " . $size ); //输出总长 } //打开文件 $fp = fopen ( "{$filePath}", "rb" ); //设置指针位置 fseek ( $fp, $range ); //虚幻输出 while ( ! feof ( $fp ) ) { print ( fread ( $fp, 1024 * 8 ) ); //输出文件 flush (); //输出缓冲 ob_flush (); } fclose ( $fp ); exit (); } $filePath = "E:/soft/PyCharm_setup.zip"; downloadBagFile ( $filePath ); 2017/7/10 22:23:49 我 2017/7/10 22:23:49 皮皮蛋 2017/07/10 22:23:49 <?php /** * Created by PhpStorm. * User: Kung * Date: 15-10-21 * Time: 下午8:00 */ set_time_limit(0); //大文件在读取内容未结束时会被超时处理,导致下载文件不全。 $fpath = 'the_file_path'; $file_pathinfo = pathinfo($fpath); $file_name = $file_pathinfo['basename']; $file_extension = $file_pathinfo['extension']; $handle = fopen($fpath,"rb"); if (FALSE === $handle) exit("Failed to open the file"); $filesize = filesize($fpath); header("Content-type:video/mpeg4");//更具不同的文件类型设置header输出类型 header("Accept-Ranges:bytes"); header("Accept-Length:".$filesize); header("Content-Disposition: attachment; filename=".$file_name); $contents = ''; while (!feof($handle)) { $contents = fread($handle, 8192); echo $contents; @ob_flush(); //把数据从PHP的缓冲中释放出来 flush(); //把被释放出来的数据发送到浏览器 } fclose($handle); exit;