2010-05-11 81 views
1

我有一個腳本,允許用戶「另存爲」一個PDF格式,這是腳本 -PHP創造巨大的錯誤,在我的服務器FEOF文件()FREAD()

<?php 
header("Content-Type: application/octet-stream"); 

$file = $_GET["file"] .".pdf"; 
header("Content-Disposition: attachment; filename=" . urlencode($file)); 
header("Content-Type: application/force-download"); 
header("Content-Type: application/octet-stream"); 
header("Content-Type: application/download"); 
header("Content-Description: File Transfer");    
header("Content-Length: " . filesize($file)); 
flush(); // this doesn't really matter. 
$fp = fopen($file, "r"); 
while (!feof($fp)) 
{ 
    echo fread($fp, 65536); 
    flush(); // this is essential for large downloads 
} 
fclose($fp); 
?> 

正在創建錯誤日誌並獲得比演出更在幾天我收到的錯誤是 -

[10-May-2010 12:38:50] PHP Warning: filesize() [<a href='function.filesize'>function.filesize</a>]: stat failed for BYJ-Timetable.pdf in /home/byj/public_html/pdf_server.php on line 10 
[10-May-2010 12:38:50] PHP Warning: Cannot modify header information - headers already sent by (output started at /home/byj/public_html/pdf_server.php:10) in /home/byj/public_html/pdf_server.php on line 10 
[10-May-2010 12:38:50] PHP Warning: fopen(BYJ-Timetable.pdf) [<a href='function.fopen'>function.fopen</a>]: failed to open stream: No such file or directory in /home/byj/public_html/pdf_server.php on line 12 
[10-May-2010 12:38:50] PHP Warning: feof(): supplied argument is not a valid stream resource in /home/byj/public_html/pdf_server.php on line 13 
[10-May-2010 12:38:50] PHP Warning: fread(): supplied argument is not a valid stream resource in /home/byj/public_html/pdf_server.php on line 15 
[10-May-2010 12:38:50] PHP Warning: feof(): supplied argument is not a valid stream resource in /home/byj/public_html/pdf_server.php on line 13 
[10-May-2010 12:38:50] PHP Warning: fread(): supplied argument is not a valid stream resource in /home/byj/public_html/pdf_server.php on line 15 

線13和15只是繼續和...我有點用PHP新手,所以任何幫助是偉大的。 謝謝你們 聶

+0

如何對某些格式進行編碼,該代碼難以讀取 – 2010-05-11 03:26:16

回答

4

發生了什麼事是:

  • 您的文件找不到,所以filesize功能errorred出
  • 因爲它出錯了,它產生的輸出。
  • 一旦你有輸出,你不能再
  • 因爲你發送更多的報頭,你得到更多的錯誤

因爲你找不到文件發送標題,while循環就會報錯了永遠的,因爲您正嘗試從不存在的文件讀取數據。

ALSO:文件有一個內容類型,而不是4.您需要選擇其中一種內容類型並使用該內容類型,但不能全部傳遞它們。

最後:你的劇本是可怕的不安全。如果有人通過?file=/home/apache/secret_db_passwords.txt,那麼他們會立即訪問你的東西。

編輯:PHP有一個名爲readfile功能是專門用來處理正是你正在嘗試做的。您不需要通過一點一點地發送文件來運行while循環。只是做readfile($file);和Web服務器將處理所有的垃圾爲你

+0

+1爲安全捕獲! – Anthony 2010-05-11 03:33:55

+0

太棒了...但現在我有點擔心,因爲我已經在衆多網站上使用這個腳本,這些網站上有敏感信息......哦,親愛的!我明白你在說什麼,我只是不確定如何實施修復程序?我剪切和粘貼該腳本,因爲這是我所有的技能允許當涉及到PHP = \ – Nik 2010-05-11 04:12:11

+0

那麼你應該設置文件名是類似的東西(像所有的字母/數字)。這樣你可以去除所有其他角色。你也可以試着去掉所有'/'的東西,但我不確定是否有一個簡單的'插件'破解來解決這個問題。但作爲一個經驗法則,你絕不應該讓用戶指定直接插入到表中的參數,或者用於訪問文件(沒有正確清理它們) – 2010-05-11 04:14:16

1

幾件事情:

  1. 只能設置一個標題一次,因爲據我所知,所以設置你的Content-Type四次無意義。

  2. 如果內容類型設置爲PDF MIME類型,在這種情況下,我與application/pdf走這可能會有幫助。

  3. Force Download不是內容類型,據我所知。如果您將Content-Disposition設置爲attachment,則瀏覽器將下載。

  4. 最後,如果有文件(這看起來沒有)沒有PDF版本,爲什麼你想從中流?你可能想你$file變量設置爲實際的文件,並讓另一個變量一樣$filename用於設置輸出到用戶的PDF文件名。

+0

從技術上講,您可以發送多個相同的標題。然而,你必須做'header(「Header」,false)'false'告訴它追加。 (但是,它從來沒有用於Content-Type標頭,因爲這沒有意義) – 2010-05-11 03:36:38

+0

我半虛張聲勢,但我很高興在這種情況下我是對的。感謝您的高舉。 – Anthony 2010-05-11 03:51:32

1
[10-May-2010 12:38:50] PHP Warning: fopen(BYJ-Timetable.pdf) [<a href='function.fopen'>function.fopen</a>]: failed to open stream: No such file or directory in /home/byj/public_html/pdf_server.php on line 12 

這應該告訴你,你需要知道:fopenfilesize都需要傳遞的名稱,並且,該文件被打開路徑。在這種情況下,您只是傳遞文件名,沒有路徑,所以它試圖在腳本運行的當前目錄中找到它。在這種情況下,要解決此問題,您需要應用一個相對或PDF文件的絕對路徑來打開這些功能,而不僅僅是PDF文件本身的名稱。