在用PHP進行文件上傳的操做中,須要知道怎麼控制上傳文件大小的設置,而文件可傳大小是受到多種因素制約的,現總結以下: php
一、php.ini:upload_max_filesize 所上傳的文件的最大大小。默認值2M。
二、php.ini:memory_limit 本 指令設定 了一個腳本所可以申請到的最大內存字節數,默認值8M。若是不須要任何內存上的限制,必須將其設爲 -1。若是內存不夠,則可能出現錯誤:Fatal error: Allowed memory size of X bytes exhausted (tried to allocate Y bytes)(通常導入數據庫時,若是數據庫太大,就會報錯,改這個就能夠)
三、php.ini:post_max_size 設定POST數據所容許的最大大小。此設定也影響到文件上傳。要上傳大文件,該值必須大於 upload_max_filesize。
四、php.ini:max_execution_time = 30 ; Maximum execution time of each script, in seconds
五、php.ini:max_input_time = 60 ; Maximum amount of time each script may spend parsing request data
六、若是用到mysql的BLOB進行二進制文件存儲,則須要設置my.ini:max_allowed_packet=xxM
七、httpd.conf
在 Apache 裏面有一個選項是 LimitRequestBody, 這個選項能夠限制用戶送出的 HTTP 請求內容。這個選項能夠在 .htaccess 或 httpd.conf 裏使用,而若是在 httpd.conf 內使用,分別能夠用在 virtualhost 或目錄屬性設定。而 LimitRequestBody 的設定值是介乎 0 (無限制) 至 2147483647 (2GB)。
例如要在目錄 D:/AppServ/www 設定上傳限制爲 100K,能夠在 .htaccess 或 httpd.conf 加入如下語句: html
若是透過 .htaccess 設定,儲存檔案後會當即生效;如透過 httpd.conf 設定,需要從新啓動 Apache。 mysql
PHP關於文件上傳部分,特別提到表單隱藏域:MAX_FILE_SIZE,意思是接收文件的最大尺寸。文檔中給出的例子以下: sql
這的確是一個很是棒的主張,但在現實中卻暫時沒法實現。不是由於這個限制能夠「被簡單地繞過」,而是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,情形又如何呢? 數據庫
問題就出在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) 瀏覽器