Предоставить файл пользователю через http через php - PullRequest
2 голосов
/ 31 августа 2010

Если я зайду http://site.com/uploads/file.pdf, я могу получить файл.

Однако, если у меня есть такой скрипт, как:

<?php 

ini_set('display_errors',1);
error_reporting(E_ALL|E_STRICT);

//require global definitions 
require_once("includes/globals.php"); 
//validate the user before continuing 
isValidUser(); 
$subTitle = "Attachment";   
$attachmentPath = "/var/www/html/DEVELOPMENT/serviceNow/selfService/uploads/";
if(isset($_GET['id']) and !empty($_GET['id'])){
    //first lookup attachment meta information 
    $a = new Attachment(); 
    $attachment = $a->get($_GET['id']); 
    //filename will be original file name with user name.n prepended 
    $fileName = $attachmentPath.$_SESSION['nameN'].'-'.$attachment->file_name; 
    //instantiate new attachmentDownload and query for attachment chunks 
    $a = new AttachmentDownload(); 
    $chunks= $a->getRecords(array('sys_attachment'=>$_GET['id'], '__order_by'=>'position')); 


    $fh = fopen($fileName.'.gz','w');                                                      
    // read and base64 encode file contents 
    foreach($chunks as $chunk){
            fwrite($fh, base64_decode($chunk->data));   
    }
    fclose($fh);

    //open up filename for writing 
    $fh = fopen($fileName,'w');     
    //open up filename.gz for extraction                                
    $zd = gzopen($fileName.'.gz', "r");
    //iterate over file and write contents 
    while (!feof($zd)) {
            fwrite($fh, gzread($zd, 60*57));    
    }
    fclose($fh); 
    gzclose($zd);
    unlink($fileName.'.gz'); 
    $info = pathinfo($fileName); 

    header('Content-Description: File Transfer');
    header('Content-Type: '.Mimetypes::get($info['extension']));
    header('Content-Disposition: attachment; filename=' . basename($fileName));
    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($fileName));
    ob_clean();
    flush();
    readfile($fileName);
    exit();
}else{
    header("location: ".$links['status']."?".urlencode("item=incident&action=view&status=-1&place=".$links['home']));   
}


?>

Это приводит к отправке мне файла, но когда я открываю его, я получаю сообщение об ошибке:

"File type plain text document (text/plain) is not supported"

Ответы [ 4 ]

1 голос
/ 31 августа 2010

Прежде всего, я бы начал с проверки заголовков HTTP.Вы можете легко сделать это в Firefox, используя расширение «Live HTTP headers»;не уверен насчет эквивалентов в других браузерах.Это позволит вам проверить, действительно ли для заголовка задано значение «application / pdf» и установлены ли другие ваши заголовки.

Если ни один из заголовков не установлен, возможно, вы случайно отправили выводдо звонков на header().Есть ли пробел перед тегом <?php?

0 голосов
/ 31 августа 2010

Попробуйте добавить "error_reporting (0);" Я нашел это в комментариях на http://php.net/readfile (откуда вы взяли этот пример).

Другая проблема, которая может быть проблемой, - это размер вашего файла. В прошлом сообщалось о проблемах, связанных с PHP5 (здесь мы говорим о 2005 году, поэтому я надеюсь, что это уже исправлено), возникающих при чтении файлов размером более 2 МБ. Если размер вашего файла превышает этот, вы можете убедиться, что он читает весь файл.

0 голосов
/ 31 августа 2010

Я использую этот, и он работает.

if(file_exists($file_serverfullpath))
{    
   header("Pragma: public");
   header("Expires: 0");
   header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
   header("Cache-Control: private", false);

   //sending download file
   header("Content-Type: application/octet-stream"); //application/octet-stream is more generic it works because in now days browsers are able to detect file anyway
   header("Content-Disposition: attachment; filename=\"" . basename($file_serverfullpath) . "\""); //ok
   header("Content-Transfer-Encoding: binary");
   header("Content-Length: " . filesize($file_serverfullpath)); //ok
   readfile($file_serverfullpath);
}
0 голосов
/ 31 августа 2010

Вы уверены, что application / pdf - это заголовок, который на самом деле видит ваш браузер?

Вы можете проверить это с помощью различных инструментов HTTP-разработчиков, например HTTP-клиент для Mac или Firebug.для Firefox.

...