2011-05-31 87 views
8

我該如何去處理一個理智的方式來處理超過post_max_size的http上傳?如何檢測用戶上傳的文件是否大於post_max_size?

在我的配置post_max_size是幾MB大於upload_max_filesize 我遇到的問題是:
如果用戶上傳文件超過post_max_size

  • 的_POST數組爲空
  • 的_FILES數組是空的,當然其中的任何錯誤代碼都不存在。
  • 沒有其他信息通過這些手段可以訪問哪種形式的帖子。

部分問題是接收腳本根據POST的內容採取不同的操作。

我確實可以使用_SERVER變量,並且可以獲得關於發生了什麼的線索,即CONTENT_TYPE,CONTENT_LENGTHREQUEST_METHOD。然而,根據這些內容進行猜測似乎很成問題。發現MEMORY_LIMIT(設置爲相關尺寸的10倍)並且Apaches LimitRequestBody(設置爲無限制)被發現沒有錯。

就目前而言,即使向用戶提供任何有意義的消息,我也很難。

有什麼方法可以保留一些表單數據,以獲得更好的線索,看看出了什麼問題?我非常不願意離開php。

回答

8

對於不需要更改服務器端的簡單修復,我會在上傳之前使用HTML5文件API來檢查文件的大小。如果超過了已知限制,則取消上傳。我相信,像這樣的工作:

function on_submit() 
{ 
    if (document.getElementById("upload").files[0].size > 666) 
    { 
    alert("File is too big."); 
    return false; 
    } 

    return true; 
} 

<form onsubmit="return on_submit()"> 
<input id="upload" type="file" /> 
</form> 

顯然,這只是一個例子的骨架,而不是每一個瀏覽器支持這一點。但是使用它並不會造成什麼傷害,因爲它可以以一種對於舊版瀏覽器來說毫不遜色的方式來實現。

當然這並不能解決這個問題,但它至少會讓很多用戶滿意,只需最少的工作量。 (他們甚至不會等待上傳失敗。)

-

順便說一句,檢查$_SERVER['CONTENT_LENGTH'] VS崗位和文件數據的大小可能幫助檢測,如果事情失敗。我認爲當出現錯誤時它將不爲零,而$_POST$_FILES都將爲空。

+0

要清楚,我會在@King Skippus的答案中引用類似的內容。即使用此客戶端解決方案讓人們開心,然後查找服務器端的空郵件並採取相應措施。 – Matthew 2011-05-31 17:18:32

+0

這很有用。我主要擔心的是無法以適當的方式通知我的用戶。任何關於當前瀏覽器支持的想法? – 2011-05-31 17:20:16

+1

@Captain長頸鹿,我認爲每個非IE瀏覽器的常見使用允許你通過JavaScript來檢查文件大小,但我並不確定。 (再一次,它會優雅地降級,所以使用它作爲解決方案的一部分沒有任何壞處。)另外,請參閱我的編輯以查看是否發生上傳問題。 – Matthew 2011-05-31 17:25:48

0

您可能需要恢復到使用閃存/ Silverlight的等,如東西: http://www.plupload.com/

還是看一個基於Java的解決方案...

基本的東西,將打破上傳到更多的可管理(和可恢復)塊,然後在服務器端重新組裝它們。

0

除非您的上傳表單中的字段不是文件輸入字段,否則$ _POST應該爲空 - 文件通過$ _FILES完全處理。非常奇怪的是,如果郵件大小超過$ _FILES將是空的 - 上傳處理程序有一個特定的錯誤代碼(1/UPLOAD_ERR_INI_SIZE)來報告這種情況。還要檢查memory_limit是否大於upload_max_filesize。

您的網絡服務器也可能阻止上載,這在PHP被調用之前就會發生。在Apache上,它由LimitRequestBody控制。

+0

是的一些其他領域,在正常情況下,有識別它是什麼樣的上傳。在這種情況下,LimitRequestBody被設置爲高於php設置,並且不會產生干擾。 – 2011-05-31 16:46:08

+0

是的,我也非常驚訝地發現_FILES因爲這個而變空了。 – 2011-05-31 16:48:08

+0

PHP和/或Apache錯誤日誌中的任何內容? – 2011-05-31 17:15:56

3

PHP documentation

如果POST數據的大小大於post_max_size中,$ _ POST和$ _FILES superglobals便會爲空。這可以通過各種方式進行跟蹤,例如,通過將$ _GET變量傳遞給處理數據的腳本,即< form action =「edit.php?processed = 1」>,然後檢查是否設置了$ _GET ['processed']。

如果您需要增加特定腳本的限制,您可以嘗試ini_set('post-max-size',$ size_needed);.不過,我不確定它是否可以在腳本中被覆蓋。這個限制可能會讓你無法做你想做的事情。

+1

我很滿意自己的限制,但並不是php超過這些限制時的反應方式。另外GET的想法是有用的,但我希望它對用戶是透明的,並且感覺「hackish」。 – 2011-05-31 16:52:30

1

我喜歡@Matthew的答案,但需要一個版本來檢查多個上傳文件。

這是我的解決方案:

function checkAttachmentsSize() { 
    var total = 0; 
    var count = 0; 

    jQuery('input[type="file"]').each(
     function() { 
      if (typeof this.files[0] != 'undefined') { 
       total+= this.files[0].size; 
       count++; 
      } 
     } 
    ); 

    var word = (count > 1) ? 's are' : ' is'; 
    if (total > (uploadMax * 1000 * 1000)) { 
     alert("The attachment file" + word + " too large to upload."); 
     return false; 
    } 

    return true; 
} 

而且,爲了完整性,這裏的函數形式的結合被提交:

jQuery(function($) { 
    $("form").submit(
     function() { 
      return checkAttachmentsSize(); 
     } 
    }); 
); 

注:
uploadMax是一個變量在計算允許上傳的最大大小之後,我通過php進行設置。

1

您可以在服務器端解決此問題,而不訴諸查詢字符串。只需將* post_max_size *設置與請求的預期內容長度進行比較即可。下面的代碼是Kohana如何做的。

public static function post_max_size_exceeded() 
{ 
    // Make sure the request method is POST 
    if (Request::$initial->method() !== HTTP_Request::POST) 
     return FALSE; 

    // Get the post_max_size in bytes 
    $max_bytes = Num::bytes(ini_get('post_max_size')); 

    // Error occurred if method is POST, and content length is too long 
    return (Arr::get($_SERVER, 'CONTENT_LENGTH') > $max_bytes); 
} 
+0

我自己並沒有處理上傳。 PHP的確如此。如果我可以從瀏覽器中截取「content_length」,那麼所有的都是粉紅色的獨角獸和蝴蝶。雖然我很欣賞你的意見。 – 2013-08-22 22:28:11

相關問題