2012-04-13 3 views
4

난 내 다운로드 스크립트를 아주 이상한 문제가 그것이 기본적으로 내 다운로드 한 파일이 항상 손상되거나 손상된 이유는 무엇입니까?

는 "GET"방법

가진 파일 ID를 1.gets

은에서 해당 파일의 이름과 위치를 2.gets 데이터베이스

는 헤더와 함께 클라이언트에 3.sends 및

하지만 일을 ReadFile을 손상되거나

손상으로 파일 rangely 항상 나오는 것처럼 파일 크기가 잘되는 zip 또는 RAR 파일 그리고 그것은

확인 열립니다하지만 난 그 안에 압축 된 파일을 열 기운과 내가 얻을 때 인 경우에 코드가 문제가 내가 심지어 zip 파일을 열 수 없습니다해야했다 (또는 적어도 내가 안) 생각하면

또 다른 한가지는 내가했습니다입니다 사촌 이상한 파일 손상 오류

모든 것을 확인하기 위해 헤더를 보내기 전에 바로 경로를 사용하여 파일을 인쇄합니다.

, 파일

그래서 모든 것이 여기

인 헤더 내 코드를 전송하기 전에 괜찮 오류없이 확인 내가 URL을 파일 주소를 넣고 파일을 다운로드 한

했다

 $file_id = isset($_GET['id']) && (int)$_GET['id'] != 0 ? (int)$_GET['id'] : exit; 


     //////// finging file info 
     $file = comon::get_all_by_condition('files' , 'id' , $file_id); 
     if(!$file) exit; 
     foreach($file as $file){ 
     $location = $file['location']; 
     $filename = $file['file_name']; 
     } 
     ///////////// 


     $site = comon::get_site_domian(); 

     $ext = trim(end(explode('.' , $filename))); 
     $abslout_path = 'http://'.$site.'/'.$location.'/'.$filename; 
     $relative = $location.'/'.$filename; 



    ////////////////// content type 
      switch($ext) { 
      case 'txt': 
       $cType = 'text/plain'; 
      break;    
      case 'pdf': 
       $cType = 'application/pdf'; 
      break; 

      case 'zip': 
       $cType = 'application/zip'; 
      break; 

      case 'doc': 
       $cType = 'application/msword'; 
      break; 

      case 'xls': 
       $cType = 'application/vnd.ms-excel'; 
      break; 

      case 'ppt': 
       $cType = 'application/vnd.ms-powerpoint'; 
      break; 
      case 'gif': 
       $cType = 'image/gif'; 
      break; 
      case 'png': 
       $cType = 'image/png'; 
      break; 
      case 'jpeg': 
      case 'jpg': 
       $cType = 'image/jpg'; 
      break; 

      default: 
       $cType = 'application/force-download'; 
      break; 
     } 
    //////////////// just checking 

    if(!file_exists($relative)){ 
     echo $relative; 
     echo '<br />'; 
     exit; 
     } 

    if(!is_readable($relative)) 
    exit('its not redable'); 



    if(headers_sent()) 
    exit('headers ? already sent !! '); 



    header('Pragma: public'); 
    header('Expires: 0'); 
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
    header('Cache-Control: private', false); // required for certain browsers 
    header('Content-Description:File Transfer'); 
    header($_SERVER['SERVER_PROTOCOL'].' 200 OK'); 
    header('Content-Type:'.$cType); 
    header('Content-Disposition: attachment; filename="'. basename($filename) . '";'); 
    header('Content-Transfer-Encoding: binary'); 
    header('Content-Length: ' . filesize($relative)); 
    readfile($abslout_path); 
    exit; 

나는 헤더를 몇 번 확인했는데 괜찮다고 생각한다. (나는 생각한다.) 나는 사람에게 알려진 모든 헤더를 덧붙였다.

문자 인코딩 또는 폴더 사용 권한과 같은 스크립트 과 다른 것일 수도 있습니다. 또는 그런 무엇인가!

내가 누락 된 항목이 있습니까?

답변

7

코드를 강제로 다운로드하는 것 같아요, 여기 항상 좋은 기능이 있습니다. 2GB 이상의 파일도 처리합니다.

<?php 
$file_id = (isset($_GET['id']) && (int)$_GET['id'] != 0) ? (int)$_GET['id'] : exit; 

/*finding file info*/ 
$file = comon::get_all_by_condition('files', 'id', $file_id); 
$path = $file['location'] . '/' . $file['file_name']; 

if (!is_file($path)) { 
    echo 'File not found.('.$path.')'; 
} elseif (is_dir($path)) { 
    echo 'Cannot download folder.'; 
} else { 
    send_download($path); 
} 

return; 

//The function with example headers 
function send_download($file) { 
    $basename = basename($file); 
    $length = sprintf("%u", filesize($file)); 

    header('Content-Description: File Transfer'); 
    header('Content-Type: application/octet-stream'); 
    header('Content-Disposition: attachment; filename="' . $basename . '"'); 
    header('Content-Transfer-Encoding: binary'); 
    header('Connection: Keep-Alive'); 
    header('Expires: 0'); 
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
    header('Pragma: public'); 
    header('Content-Length: ' . $length); 

    set_time_limit(0); 
    readfile($file); 
} 
?> 
+0

후보기를 계속 렌더링 때문에 마지막 줄에 die(); 또는 exit();를 추가했다 readfile(FILE_NAME)

마지막 줄 후에 실행 코드가없는 있는지 확인 고맙습니다 잘 작동합니다 – max

+0

@DanBray 끔찍한 편집, 승인을위한 공동체에 대한 수치심 –

+0

@LawrenceCherone 코드 작동에 대해 끔찍한 것은 무엇입니까? 코드에 누락 된')'이 있습니다. 오타가있는 코드를 남겨 두는 것이 낫다고 생각합니까? 빠진'')은 사람들을 혼란에 빠뜨릴 수 있고 많은 시간을 낭비 할 수 있습니다. –

2

, 오류가 스크립트의 상부에보고하지 않도록하려고주의 또는 경고를 포함 할 수 있습니다 귀하의 스크립트를

error_reporting(0); 
2
아주 좋은, 도움도

...

하지만 문제의가있다 코드 -

header('Content-Disposition: attachment; 
filename="'.basename($file).'"'; 

이 다음과 같이 변경하십시오 -

header('Content-Disposition: attachment; 
filename="'.basename($file).'"'); 

당신이 그것을 잊어 버리는 것을 잊어 버렸습니다.

2
if (file_exists($file)) { 
set_time_limit(0); 
     header('Connection: Keep-Alive'); 
    header('Content-Description: File Transfer'); 
      header('Content-Type: application/octet-stream'); 
      header('Content-Disposition: attachment; filename="'.basename($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: ' . filesize($file)); 
      ob_clean(); 
      flush(); 
      readfile($file); 


} 
+0

이것은 나를 위해 완벽하다. 다운로드 한 파일이 손상되지 않습니다. Lawrence Cherone은 PHP 스크립트를 제안했지만 다운로드 한 파일은 여전히 ​​손상되었습니다. Altair CA 덕택입니다. 그리고 모두에게 감사드립니다. –

0

당신은 내가 MVC 프레임 워크는 readfile

관련 문제