2012-04-13 18 views
4

ich habe ein sehr seltsames Problem mit meinem Download-SkriptWarum ist meine heruntergeladene Datei immer beschädigt oder beschädigt?

es im Grunde

1.gets eine Datei-ID mit der Methode „GET“

2.gets den Namen und Speicherort der Datei aus

Datenbank

3.sends es an den Client mit den Kopf- und ReadFile-

aber st rangely, die immer Datei kommt als beschädigt oder

beschädigt wie wenn es eine zip oder rar-Datei Dateigröße richtig ist, und es öffnet ok

aber ich kann nicht in der es Öffnen von komprimierten Dateien und das ist, wenn ich das bekommen Datei beschädigt Fehler

die seltsam cuz, wenn der Code ein Problem hatte ich die Zip-Datei öffnen können, nicht einmal sollte (oder zumindest ich glaube, ich sollte nicht)

andere Sache ist, ich habe Drucken Sie die Datei mit dem Pfad aus, bevor Sie die Header senden, um sicherzugehen, dass alles in Ordnung ist

ich die Datei-Adresse auf der URL gesetzt haben und die Datei herunterladen, war Datei ohne Fehler ok

so alles, was die Header

vor dem Senden hier

meinen Code

in Ordnung ist ist
 $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; 

Ich habe die Header paar mal überprüft und sie sind in Ordnung (ich denke), ich habe auch alle Header, um den Menschen bekannt, nur um sicher zu sein!

Ich fange an zu denken, es ist vielleicht etwas anderes als Skript wie Char-Codierung oder Ordner-Erlaubnis! oder etwas ähnliches !!

bin ich etwas fehlt?

Antwort

7

Das scheint allot Code nur zu zwingen-Download, hier ist eine nette Funktion, die ich die ganze Zeit verwenden. Es wird auch Dateien über 2 GB verarbeiten.

<?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

machen weiter thanx funktioniert gut – max

+0

@DanBray was für eine schreckliche Bearbeitung, Schande über die Gemeinschaft für die Genehmigung –

+0

@LawrenceCherone Was ist so schrecklich über den Code arbeiten? Der Code hatte eine fehlende ')'. Denkst du es ist besser Code mit Tippfehlern zu lassen? Das fehlende ')' könnte Menschen verwirren und viel Zeit verschwenden. –

2

Ihr Skript kann ACHTUNG oder WARNUNG enthalten, versuchen Fehler auf Anfang des Skripts Berichterstattung zu deaktivieren:

error_reporting(0); 
2

Sehr schön, nützlich auch ...

aber es gibt ein Problem in Ihr Code -

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

bitte mit diesem folgenden ändern -

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

Sie sind vergessen, es zu schließen.

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

Das ist perfekt für mich. Die heruntergeladene Datei ist nicht beschädigt. Ich benutze als Lawrence Cherone das vorgeschlagene PHP-Skript, aber die heruntergeladene Datei ist immer noch korrupt. Danke an Altair CA. Und danke an alle. –

0

Stellen Sie sicher, Sie haben keine nach der letzten Zeile ausgeführten Code readfile(FILE_NAME)

I die(); oder exit(); als letzte Zeile hinzugefügt hatte, weil MVC-Framework die Ansicht nach readfile

Verwandte Themen