檢查$_POST內容是否超過限制

$_POST的大小限制設定在php.ini的post_max_size這個指令裡,我們可以直接指定以byte為單位的數字,例如1024,也可以直接加上單位,例如1K,但1和K之間不能有任何空格,否則就會出現Internal Server Error的訊息。另外,根據php官網的訊息,上述單位最大可使用到g。

雖然有指定post的大小限制,但當超過限制的時候,可能不一定能夠看到錯誤訊息,這取決於php.ini裡的display_startup_errors指令是否設為on,當此指令設為off(預設)時,我們是看不到錯誤訊息的。

除了看不到錯誤訊息之外,它還會連帶影響到$_FILES陣列的判別。原來是當表單大小超過post_max_size的設定後,$_POST就會直接「爆炸」,就好像氣球灌太多氣直接爆炸一樣,結果幾乎什麼都沒有剩下,只剩下$_SERVER[‘CONTENT_LENGTH’]還有記錄原始的表單大小,$_FILES也不會產生,連空陣列都不是,這樣也就沒有辦法利用$_FILES[filename][‘error’]來判斷上傳檔案的錯誤。

因為超過限制時$_POST會變成空陣列,我們也沒有辦法使用if($_POST)來正確判別當次是否為post過來的資料,而且在display_startup_errors為off的情況下還不會顯示任何錯誤訊息,這會讓人小傷腦筋一番。

所幸post過來的狀況下,$_SERVER有一些訊息還蠻有用的,例如$_SERVER[‘REQUEST_METHOD’]代表是使用POST或是GET,$_SERVER[‘CONTENT_LENGTH’]則是代表原始上傳表單的大小,我們可以拿它來和upload_max_filesize這個指令設定的值來比較。如果$_SERVER[‘REQUEST_METHOD’]是POST,而且upload_max_filesize大於$_SERVER[‘CONTENT_LENGTH’],代表此次表單是以POST的方式上傳,而且大小大限制之內,可以繼續做處理,反之就必須提供錯誤訊息來提示使用者。

所以我就寫了一個函數來做這樣子的判別:

function is_post(){

$val = trim(ini_get(“upload_max_filesize”));

$last = strtolower($val[strlen($val)-1]);

//需對upload_max_filesize指令的值做一些處理,轉換為以byte為單位

switch($last) {

// The ‘G’ modifier is available since PHP 5.1.0

case ‘g’:

$val *= 1024;

case ‘m’:

$val *= 1024;

case ‘k’:

$val *= 1024;

}

if($_SERVER[‘REQUEST_METHOD’]==‘POST’){

if($val >= $_SERVER[‘CONTENT_LENGTH’]){

return true;

}else{

trigger_error(“上傳表單大小超過限制!”,E_USER_WARNING);

}

}

}

最後說明一個問題,在其他網站有看到一些說明,指出memory_limit這個指令也和post_max_size相關,不過經測 試,memory_limit和post_max_size大小沒有關係,此次測試環境在Apache Web Server Version 2.2.8、PHP Script Language Version 5.2.6、Windows Xp。

參考來源:

1:http://tw.php.net/manual/en/function.ini-get.php

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

Proudly using Dynamic Headers by Nicasio WordPress Design