2012-04-13 7 views
4

j'ai un problème très bizarre avec mon script de téléchargementpourquoi mon fichier téléchargé est toujours endommagé ou corrompu?

il essentiellement

1.gets un identifiant de fichier avec la méthode « GET »

2.gets le nom et l'emplacement de ce fichier à partir base de données

3.sends au client avec les en-têtes et READFILE

mais st Rangely ce fichier toujours apparaît comme corrompus ou endommagés

comme si c'est un fichier zip ou rar taille du fichier est juste et il ouvre ok

mais je ne peux pas ouvrir les fichiers compressés à l'intérieur de celui-ci et qui est quand je reçois la fichier d'erreur endommagé

ce qui est bizarre cuz si le code avait un problème que je ne devrais même pas être en mesure d'ouvrir le fichier zip (ou au moins je pense que je ne devrais pas)

une autre chose que j'ai est imprimé le fichier avec son chemin juste avant d'envoyer les en-têtes juste pour être sûr que tout va bien

j'ai mis l'adresse du fichier sur l'URL et télécharger le fichier, le fichier est correct sans erreur

si tout va bien avant d'envoyer les en-têtes

Voici mon code

 $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; 

J'ai vérifié les en-têtes quelques fois et ils sont bien (je pense), j'ai aussi ajouté tous les en-têtes connus à l'homme juste pour être sûr!

Je commence à penser que c'est peut-être quelque chose d'autre que le script comme l'encodage de caractères ou la permission de dossier! ou quelque chose comme ça !!

ai-je oublié quelque chose?

Répondre

7

Cela semble attribuer beaucoup de code juste pour forcer le téléchargement, voici une bonne fonction que j'utilise tout le temps. Il va gérer les fichiers de plus de 2 Go aussi.

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

thanx fonctionne très bien – max

+0

@DanBray quelle édition terrible, honte à la communauté pour approbation –

+0

@LawrenceCherone Qu'est-ce qui est si terrible de faire fonctionner le code? Le code manquait ')'. Pensez-vous qu'il est préférable de laisser le code avec des fautes de frappe? Le ')' manquant pourrait dérouter les gens et perdre beaucoup de leur temps. –

2

Votre script peut contenir ou AVIS AVERTISSEMENT, essayez de désactiver l'erreur de rapports sur le dessus de votre script:

error_reporting(0); 
2

Très gentil, serviable aussi ...

mais il y a un problème dans votre code -

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

s'il vous plaît changer avec ce qui suit -

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

vous avez oublié de le fermer.

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

C'est parfait pour moi. Le fichier téléchargé n'est pas corrompu. J'utilise comme script PHP suggéré Lawrence Cherone mais le fichier téléchargé est toujours corrompu. merci à Altair CA. Et merci à tous. –

0

Assurez-vous de ne pas code exécuté après la dernière ligne readfile(FILE_NAME)

je devais ajouter die(); ou exit(); la dernière ligne, car framework MVC continue de rendre la vue après readfile

Questions connexes