通过PHP通过HTTP向用户提供文件

如果我转到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" 

首先,我将首先检查HTTP头。 您可以使用“Live HTTP标头”扩展名轻松地在Firefox中执行此操作; 不知道其他浏览器中的等价物。 这将让你验证,如果头实际上被设置为“应用程序/ pdf”,并且您的其他头是否也被设置。

如果没有设置标题,则可能是在调用header()之前无意中发送了输出。 在<?php标签之前是否有空格?

你确定application / pdf是你的浏览器实际看到的标题吗?

您可以使用各种HTTP开发工具来检查,例如Mac的HTTP客户端或Firefox的Firebug。

我使用这一个,它的工作原理。

 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); } 

尝试预先添加“error_reporting(0);”。 我在http://php.net/readfile的注释中找到了这个(你从这个例子中得到了这个例子)&#x3002;

另一个可能成为问题的是你的文件大小。 过去有一些关于PHP5的问题(我们在这里讨论2005,所以我希望现在已经解决了)阅读文件大于2MB有困难。 如果您的文件大小超过这个,您可能需要验证它是否读取整个文件。