標籤:
PHP VERSION = 5.3.10
一、關於 $_REQUEST
PHP 文檔關於 $_REQUEST 的說明:
說明預設情況下包含了 $_GET,$_POST 和 $_COOKIE 的數組。更新日誌版本 說明5.3.0 引入 request_order。該指令會影響 $_REQUEST 的內容。4.3.0 $_FILES 資訊被從 $_REQUEST 中移除。4.1.0 引入 $_REQUEST。
在 php 5.3 以上版本中,php.ini 中的 request_order 預設設定為:
request_order = "GP"
GP 即 GET 和 POST,並不包含"C"(COOKIE),即 $_REQUEST 預設只包含 $_GET 和 $_POST。
【例】
form.html
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>表單</title></head><body> <form action="doAction.php?username=deathMask" method="post"> 使用者名稱: <input type="text" name="username"> <input type="submit" value="提交"> </form></body></html>
doAction.php
<?phpvar_dump($_REQUEST[‘username‘]);
此時:在使用者名稱輸入框中輸入 dee,則輸出:
string ‘dee‘ (length=3)
但是如果修改 php.ini 中 request_order 值的順序:
將預設的GP 改為 PG,
request_order = "PG"
即 $_GET 和 $_POST 同鍵時,$_GET 的值會覆蓋 $_POST 的值,此時提交表單,輸出:
string ‘deathMask‘ (length=9)
二、 確定請求是 get 方法 還是 post 方法:$_SERVER[‘REQUEST_METHOD‘]
【例】
form.html
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>表單</title></head><body> <form action="doAction.php" method="post"> 使用者名稱: <input type="text" name="username"> <input type="submit" value="提交"> </form></body></html>
doAction.php:
<?phpecho $_SERVER[‘REQUEST_METHOD‘];
如果通過 form.html 提交表單,則 doAction.php 輸出:POST
如果直接存取 doAction.php,則輸出:GET
【例】根據請求的方法決定做什麼(GET 輸出介面,POST 輸出資料)
<?php if($_SERVER[‘REQUEST_METHOD‘] == ‘GET‘){?><form action="<?php echo $_SERVER[‘SCRIPT_NAME‘];?>" method="post">使用者名稱:<input type="text" name="username"><input type="submit" value="提交"></form><?php }else{ echo ‘Hello, ‘.$_POST[‘username‘];} ?>
三、 驗證必要欄位
方案:使用 strlen() 來測試 $_GET 或 $_POST 中的元素值
if(!strlen($_POST[‘username‘])){ echo ‘不可為空‘;}else{ echo ‘Hello, ‘.$_POST[‘username‘];}
注意:不同類型的表單元素留空會對 $_GET 和 $_POST 中的元素值不盡相同。空文字框、空文本地區及空的檔案上傳域的值是零長度字串;而未選中的複選框和選項按鈕,不會在 $_GET 和 $_POST 中產生任何值;瀏覽器通常會強迫在單選下拉式清單中選中一個項目,而對於多選下拉式清單,如果沒有選中其中任何一個項目,則結果和複選框是一樣的,不會在 $_GET 或 $_POST 中產生任何值。
不僅如此,就連請求本身也並非只能來自 網頁瀏覽器(利用漏洞惡意攻擊)。
最嚴格的表單驗證應該:step1. 使用 isset() 檢查這個元素受否存在於 $_GET 或 $_POST 中; step2. 如果元素包含在一個數組中(複選框),可以使用 is_array() 來驗證是否存在於一個數組。
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>驗證必要欄位</title></head><body> <h1>使用isset()、strlen()和is_array() 完成嚴格的表單驗證</h1> <?php if($_SERVER[‘REQUEST_METHOD‘] == ‘GET‘){?> <form action="<?php echo $_SERVER[‘SCRIPT_NAME‘];?>" method="post"> 使用者名稱:<input type="text" name="username"> *必填<br /><br /> 愛好:<input type="checkbox" name="hobby[]" id="">足球 <input type="checkbox" name="hobby[]" id="">足球 <input type="checkbox" name="hobby[]" id="">閱讀 <input type="checkbox" name="hobby[]" id="">編程 <input type="checkbox" name="hobby[]" id="">音樂 <input type="checkbox" name="hobby[]" id="">電影<br /><br /> <input type="submit" value="提交"> </form> <?php }else{ //在檢查長度之前,先檢查$_POST[‘username‘]是否存在 if(!strlen($_POST[‘username‘])){ echo ‘請輸入使用者名稱<br />‘; } //確保 $_POST[‘hobby‘] 存在並且是一個數組 if(!(isset($_POST[‘hobby‘]) && is_array($_POST[‘hobby‘]))){ echo ‘請至少選擇一項<br />‘; } } ?></body></html>
注意:根據 PHP 的布爾值計算規則,字元0 可以轉換為 false,因此嘗試使用 empty() 代替 strlen() 可能會導致問題 —— 如果在 children 文字框中填入 0,則 $_POST[‘children‘] 的值為0,而 empty($_POST[‘children‘]) 測試的結果為 true,從驗證表單的角度來說是錯誤的。
【例】
<?phpif(empty($_POST[‘username‘])){ echo ‘空‘;}else{ echo $_POST[‘username‘];}
當輸入0時,輸出 空。
四、 驗證表單輸入:數字
方案:如果要確定值是否為大於或等於0的整數,可以使用函數 ctype_digit()。
<?phpif(!ctype_digit($_POST[‘age‘])){ echo ‘年齡必須大於等於0‘;}
(待續)
參考:
①《PHP 經典執行個體》
② php中使用$_REQUEST需要注意的一個問題
PHP / JavaScript / jQuery 表單驗證與處理總結: 第①部分 PHP 表單驗證與處理