2011-10-17 45 views
0

我使用下面的閱讀和報告的PDF文件到用戶:PHP:讀取並呈現PDF文件,通過PHP下載是產生在某些情況下損壞的文件

$file='file.pdf'; 
$filepath="/path-to-download-folder/$file"; 
if(!is_file($filepath)) die('Ops!'); 
$f=fopen($filepath,'r'); 
if($f){ 
    header('Cache-Control: no-store, no-cache, must-revalidate'); 
    header('Content-Type: '.mime_content_type($filepath)); 
    header('Content-Length: '.filesize($filepath)); 
    header('Content-Disposition: attachment; filename="'.$file.'"'); 
    fpassthru($f); 
}else die("Ops!"); 
fclose($f); 

然而,一些人報告PDF文件在嘗試打開時已損壞。

我做錯了什麼或忘記了一些重要的標題?有沒有更好的方法來實現相同?

UPDATE:

我通過電子郵件發送的PDF文件,用戶一定要打開該文件。所以它必須是PHP和Nginx爲文件提供服務的方式。

因此,我關閉了Nginx上的gzip,但錯誤仍在繼續。

我還應用了尖端婁這樣的代碼是現在這個樣子:

$file='file.pdf'; 
$filepath="/path-to-download-folder/$file"; 

if(!file_exists($filepath)){ 
    header('HTTP/1.1 404 Not Found'); 
    exit; 
}elseif(!is_file($filepath) or !is_readable($filepath)){ 
    header('HTTP/1.1 403 Forbidden'); 
    exit; 
}else{ 
    header('Cache-Control: no-store, no-cache, must-revalidate'); 
    header('Content-Type: '.mime_content_type($filepath)); 
    header('Content-Length: '.filesize($filepath)); 
    header('Content-Disposition: attachment; filename="'.$file.'"'); 

    set_time_limit(0); // Big files/slow connections may result in incomplete downloads 
    readfile($filepath); 
    die; 
} 

不過,我還是我收到此錯誤:http://mlkshk.com/r/8FGS

UPDATE:

我做了一個差異其中包括:

compare -verbose -debug coder Dicas1.pdf Dicas1A.pdf -compose src OUT.tmp 

有了這個輸出:

"gs" -q -dQUIET -dPARANOIDSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=0 "-sDEVICE=pnmraw" -dTextAlphaBits=4 -dGraphicsAlphaBits=4 "-r72x72" "-sOutputFile=/tmp/magick-XXuCqreY" "-f/tmp/magick-XXNkQbcr" "-f/tmp/magick-XXoICX9T" 
    **** Warning: File has some garbage before %PDF- . 
    **** Error: Cannot find a %%EOF marker anywhere in the file. 
    **** Warning: An error occurred while reading an XREF table. 
    **** The file has been damaged. This may have been caused 
    **** by a problem while converting or transfering the file. 
    **** Ghostscript will attempt to recover the data. 

所以我在Leafpad打開一看:

原始文件:

%PDF-1.5 
%Çì¢ 
1 0 obj 
<< 
/Type /Catalog 
/Outlines 3 0 R 
/Pages 4 0 R 
/Dests 5 0 R 
/AcroForm 6 0 R 
/Names 7 0 R 
/Threads 8 0 R 
/PageLayout /SinglePage 
/ViewerPreferences 
<< 
/PageDirection /L2R 
>> 
>> 
endobj 
2 0 obj 
<< 
/Creator (Scribus 1.5.0.svn) 
/Producer (Scribus PDF Library 1.5.0.svn) 
/Title <> 
/Author <> 
/Subject <> 
/Keywords <> 
/CreationDate (D:20111016162546Z) 
/ModDate (D:20111016162546Z) 
/Trapped /False 
>> 
endobj 
9 0 obj 
<< 
/Length 154566 
/Length1 275572 
/Filter /FlateDecode 
>> 
stream 

文件由PHP和Nginx的送達:

6Wm931Ja.G46X5WID+1K9G93F.3FD.2IXCWm<br>%PDF-1.5 
%Çì¢ 
1 0 obj 
<< 
/Type /Catalog 
/Outlines 3 0 R 
/Pages 4 0 R 
/Dests 5 0 R 
/AcroForm 6 0 R 
/Names 7 0 R 
/Threads 8 0 R 
/PageLayout /SinglePage 
/ViewerPreferences 
<< 
/PageDirection /L2R 
>> 
>> 
endobj 
2 0 obj 
<< 
/Creator (Scribus 1.5.0.svn) 
/Producer (Scribus PDF Library 1.5.0.svn) 
/Title <> 
/Author <> 
/Subject <> 
/Keywords <> 
/CreationDate (D:20111016162546Z) 
/ModDate (D:20111016162546Z) 
/Trapped /False 
>> 
endobj 
9 0 obj 
<< 
/Length 154566 
/Length1 275572 
/Filter /FlateDecode 
>> 
stream 

所以這PHP是垃圾文件的開頭部分:

6Wm931Ja.G46X5WID+1K9G93F.3FD.2IXCWm<br>

而且我發現一個會話值被迴盪在代碼的另一部分,那就是從一開始真正的問題。

謝謝。

+0

破損的文件是什麼樣的在文本或十六進制編輯器中打開時是否內部?任何PHP錯誤消息? –

+4

損壞如何? 0字節文件?最後切斷?額外的文字嵌入在某處?除此之外,使用'is_readable()'而不是is_file。 is_readable更重要,因爲有許多文件不能被讀取,但會通過is_file()檢查。 –

+0

我試圖獲得這些信息,但是我沒有從報道這一點的人那裏得到任何線索。我用不同的瀏覽器嘗試了很多次,並始終保持PDF格式不變。但我有一個很好的互聯網連接,我是一個Linux用戶... – Roger

回答

2

到目前爲止,像這樣的問題最常見的原因是在<?php ?>標籤之前/之後的前/後空白。請注意,您可能不需要?>標記,這有助於避免此問題。

接下來最常見的原因是在輸出文件後忘記調用exit/die

請檢查以上兩點。

編輯

這是我會怎麼寫代碼:

$file = 'file.pdf'; 
$filepath = "/path-to-download-folder/$file"; 

if (!file_exists($filepath)) { 
    header('HTTP/1.1 404 Not Found'); 
    exit; 
} else if (!is_file($filepath) || !is_readable($filepath)) { 
    header('HTTP/1.1 403 Forbidden'); 
    exit; 
} 

header('Cache-Control: no-store, no-cache, must-revalidate'); 
header('Content-Type: '.mime_content_type($filepath)); 
header('Content-Length: '.filesize($filepath)); 
header('Content-Disposition: attachment; filename="'.$file.'"'); 

set_time_limit(0); // Big files/slow connections may result in incomplete downloads 
readfile($filepath); 

exit; 
+0

嗯,我只在「elseif」之後和「標題」之前插入了一個「else」,儘管它不是真的有必要。我做了一個測試,它工作。現在我會等待客戶的任何意見。我會回到這裏發佈結果。謝謝。 – Roger

+0

One Mac用戶發佈了錯誤信息:http://mlkshk.com/r/8FGS – Roger

+1

對不起,你能告訴我這是什麼意思嗎?因爲它是一個圖像,我不能複製/粘貼到翻譯器中......另外,我們真正需要的是原始文件和損壞版本之間的字節比較,所以我們可以嘗試解決它的方式/位置損壞。 – DaveRandom

1

此外,你應該以二進制模式打開PDF文件:

$f = fopen($filepath, 'rb'); 

(或者你可以只需使用readfile()。)