2010-04-09 20 views
0

過去3個月,我的網站一直在使用PHP文件處理程序與htaccess的組合。 用戶訪問該站點的上傳文件夾將被重定向到處理程序這樣:文件處理程序返回亂碼文件

RewriteRule ^(.+)\.*$ downloader.php?f=%{REQUEST_FILENAME} [L] 

文件處理機的目的是僞以下編碼,隨後實際代碼。

//Check if file exists and user is downloading from uploads directory; True. 
//Check against a file type white list and set the mime type(); $ctype = mime type; 
header("Pragma: public"); // required 
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-Type: $ctype"); 
header("Content-Disposition: attachment; filename=\"".basename($filename)."\";"); 
header("Content-Transfer-Encoding: binary"); 
header("Content-Length: ".filesize($filename)); 
readfile("$filename"); 

截至昨天,處理程序開始返回亂碼文件,無法讀取的圖像,並且必須被繞過。我想知道什麼設置可能會導致此錯誤。

CNC中

發現問題,但沒有解決。包括我用於與Wordpress集成的php庫的路徑是破壞文件。刪除該代碼塊可解決損壞問題,但會使文件無需所需的身份驗證即可訪問。

@include_once($_SERVER['DOCUMENT_ROOT'].'/wp-blog-header.php'); 
    if(!is_user_logged_in()) 
    { 
    auth_redirect(); //Kicks the user to a login page. 
    } 

    //resume download script 
+3

您可能會收到一些錯誤消息,然後將其作爲文件內容進行處理。看看文件內容。 – Gumbo 2010-04-09 18:45:17

+1

您不需要將'$ filename'作爲'readfile'的參數包裝在一個字符串中。這很好:'readfile($ filename)'。任何時候你都可以避免字符串插值是好的。 – 2010-04-09 19:00:07

+0

字符串插值是固定的,但沒有區別。文件越來越受損,並且其中有很多原始數據,而.pdfs不受影響。圖像,微軟格式都變得亂碼。 – ForCripeSake 2010-04-09 19:05:29

回答

1

也許更多的測試將揭示問題...

if (!isset($filename)) { 
    die('parameter "filename" not set'); 
} 
else if (!file_exists($filename)) { 
    die('file does not exist'); 
} 
else if (!is_readable($filename)) { 
    die('file not readable'); 
} 
else if (false===($size=filesize($filename))) { 
    die('stat failed'); 
} 
else if (headers_sent() || ob_get_length()>0) { 
    die('something already sent output.'); 
} 
else { 
    $basename = basename($filename); 

    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-Type: $ctype"); 
    header("Content-Disposition: attachment; filename=\"".$basename."\";"); 
    header("Content-Transfer-Encoding: binary"); 
    header("Content-Length: ".$size); 
    readfile($filename); 
} 
+0

看着這個代碼(謝謝btw),似乎頭已經被髮送。進一步調查。 – ForCripeSake 2010-04-09 20:24:34

0

如何的文件受到損壞?截斷? 0字節?完全不同的內容?隨機部分換成垃圾?

是否有可能服務器的PHP內存限制已降低?在輸出之前,readfile()會將整個文件緩衝在內存中。因此,一個40meg文件將失敗,內存限制是39.9999,有點類似。

對於文件流媒體用戶,最好不要使用PHP自己的「轉儲文件瀏覽器」功能,因爲他們都受內存限制。最好做一個fopen/fwrite/fclose循環,並以小巧的可管理塊(4k,16k等)吐出文件。

+0

ReadFile的()要麼使用內存映射文件或8K的緩衝液(其是不受memory_limit的),參見'PHPAPI爲size_t _php_stream_passthru(php_stream *流STREAMS_DC TSRMLS_DC)'在主/流/ streams.c,HTTP:// CVS .php.net/viewvc.cgi/PHP-SRC /主/流/ streams.c?=視圖日誌 – VolkerK 2010-04-09 19:59:49