【轉載】解決Apache2+PHP上傳檔案大小限制的問題

來源:互聯網
上載者:User

標籤:c   style   blog   a   http   ext   

原文出處:http://evol1216.blog.163.com/blog/static/13019958020106783623528/

在用PHP進行檔案上傳的操作中,需要知道怎麼控制上傳檔案大小的設定,而檔案可傳大小是受到多種因素制約的,現總結如下:

1、php.ini:upload_max_filesize 所上傳的檔案的最大大小。預設值2M。

2、php.ini:memory_limit 本 指令設定 了一個指令碼所能夠申請到的最大記憶體位元組數,預設值8M。如果不需要任何記憶體上的限制,必須將其設為 -1。如果記憶體不夠,則可能出現錯誤:Fatal error: Allowed memory size of X bytes exhausted (tried to allocate Y bytes)(一般匯入資料庫時,如果資料庫太大,就會報錯,改這個就可以)

3、php.ini:post_max_size 設定POST資料所允許的最大大小。此設定也影響到檔案上傳。要上傳大檔案,該值必須大於 upload_max_filesize。

4、php.ini:max_execution_time = 30 ; Maximum execution time of each script, in seconds

5、php.ini:max_input_time = 60 ; Maximum amount of time each script may spend parsing request data

6、如果用到mysql的BLOB進行二進位檔案儲存,則需要設定my.ini:max_allowed_packet=xxM

7、httpd.conf
    在 Apache 裡面有一個選項是 LimitRequestBody, 這個選項可以限制使用者送出的 HTTP 要求內容。這個選項可以在 .htaccess 或 httpd.conf 裡使用,而如果在 httpd.conf 內使用,分別可以用在 virtualhost 或目錄屬性設定。而 LimitRequestBody 的設定值是介乎 0 (無限制) 至 2147483647 (2GB)。
例如要在目錄 D:/AppServ/www 設定上傳限制為 100K,可以在 .htaccess 或 httpd.conf 加入以下語句:

 
  1. LimitRequestBody 1024000000
  2. Options Indexes FollowSymLinks MultiViews ExecCGI
  3. AllowOverride All
  4. Order allow,deny
  5. Allow from all
 

如果透過 .htaccess 設定,儲存檔案後會立即生效;如透過 httpd.conf 設定,須要重新啟動 Apache。

PHP關於檔案上傳部分,特別提到表單隱藏欄位:MAX_FILE_SIZE,意思是接收檔案的最大尺寸。文檔中給出的例子如下:
 

 
  1. <form enctype="multipart/form-data" action="_URL_" method="POST">
  2.     <input type="hidden" name="MAX_FILE_SIZE" value="30000">
  3.     Send this file: <input name="userfile" type="file">
  4.     <input type="submit" value="Send File">
  5. </form>
 


這裡設定MAX_FILE_SIZE = 30000,期待一種可能,使得瀏覽器在傳送檔案之前能夠依此作出預先判斷,如果檔案尺寸大於30000位元組,則不執行實際的POST動作。也就是不往服 務器傳送檔案內容,而是直接在用戶端提醒使用者“你試圖上傳的檔案超過30000位元組”。
這的確是一個非常棒的主張,但在現實中卻暫時無法實現。不是因為這個限制可以“被簡單地繞過”,而是IE和FireFox這兩個主流瀏覽器都不支援這個特性。PHP的這個建議尚未被採納。

MAX_FILE_SIZE還有一個用場:後台PHP會判斷已接收的檔案大小是否大於這個值,如果超出,$_FILES[‘thisfile‘] [‘error‘]會被設定為UPLOAD_ERR_FORM_SIZE(2),同時放棄儲存臨時檔案,將$_FILES[‘thisfile‘] [‘size‘]置0。
這個例子,沒問題,表現正常,當我試圖上傳一個40多K的檔案時,PHP程式報告“檔案超過MAX_FILE_SIZE”。
但是,如果我們將表單中的MAX_FILE_SIZE從30000減少到1000,情形又如何呢?

  • 上傳800位元組的檔案,正常;
  • 上傳40K的檔案,PHP報告檔案過大,也正常;
  • 上傳3000個位元組的檔案,PHP未報告錯誤,它成功儲存了檔案!出乎意料!

問題就出在main/rfc1867.c中 判斷檔案是 否超長的這部分代碼上。php每次從buffer中讀取FILLUNIT位元組長度的內容後,首先判斷“已經讀到的內容長度(total_bytes)”是 否大於MAX_FILE_SIZE,然後再增加“已經讀到的內容長度(total_bytes)”。這樣一來,和預計的結果之間至多會有FILLUNIT 位元組的誤差,而FILLUNIT=1024*5=5K。(點擊bug瞭解詳細內容)
這就是說,當MAX_FILE_SIZE<5K時,上傳一個大於MAX_FILE_SIZE,但是小於5K的檔案是沒有問題的。
當然,因為這個設定很容易被繞過,所以伺服器端編程不應當依賴於MAX_FILE_SIZE。而且,5K到底是個很小的數值,對大多數上傳檔案的表單來說沒有影響。

 PHP中post_max_size,upload_max_filesize, MAX_FILE_SIZE的設定,和用戶端上傳給伺服器端的流量大小無關。
Apache伺服器從用戶端接收長度不超過LimitRequestBody位元組數的請求,然後傳送給php模組,php模組再決定是否儲存成臨時檔案,設定$_FILES全域變數,移交給script進一步處理。
這個Apache的LimitRequestBody選項預設值=0,允許Request body的最大位元組數是2G(Linux + Apache)

最後還要注意的是:
html本身能夠post資料也是有限制的,不能超過2G。
FTP用戶端有檔案位移指標的2GB邊界限制,未使用特殊編譯flag編譯的ftp伺服器端或者用戶端,無論在什麼FS中都不支援大於2GB的檔案。不知道PHP會不會也有這種情況。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.