PHP Data Filtering
PHP: 7.2
PHP 提供了一系列 Data Filter 的函式,主要是用來驗證(Validation)和過濾(Sanitization)。
根據 Filter Input - Escape Output
的原則,通常會用來 Filter 來自外部的 Input,例如網站表單的輸入、Cookie 等資訊,以確保能夠得到正確的資料類型。
Filter Functions
Filter Functions 是決定 Filter 的資料來源和型態。
以下為幾個較為常用的 Filter Functions: Function Name |
Description |
---|---|
filter_has_var | 檢查 Input 中是否有指定的變數 |
filter_input | 過濾 Input 變數 |
filter_input_array | 同時過濾多個 Input 變數 |
filter_var | 針對變數過濾 |
filter_var_array | 針對多個變數(陣列)過濾 |
Filter Type
Filter Type 是決定 Filter 規則的屬性,通常還會再搭配 Options
和 Filter Flags 建立額外的規則。
以下為幾個較為常用的 Filter Type: Type Name |
Description |
---|---|
FILTER_CALLBACK | 可以自行定義 Filter 處理 |
FILTER_VALIDATE_INT | 判斷數字是否有在範圍內 |
FILTER_VALIDATE_BOOLEAN | 判斷布林值,1、 true 、 on 、 yes 都會判斷成 true ,反之為 false ,若是這些以外的值會回傳 NULL |
FILTER_VALIDATE_FLOAT | 判斷是否為浮點數 |
FILTER_VALIDATE_REGEXP | 利用 regexp 做驗證 |
FILTER_VALIDATE_URL | URL 驗證 |
FILTER_VALIDATE_EMAIL | e-mail 驗證 |
FILTER_VALIDATE_IP | IP 驗證 |
FILTER_SANITIZE_STRING | 去除標籤或特殊字元(HTML 標籤會被過濾) |
FILTER_SANITIZE_ENCODED | 與 urlencode() 類似 |
FILTER_SANITIZE_MAGIC_QUOTES | 過濾針對 SQL injection 做過濾(例如單、雙引號) |
FILTER_SANITIZE_SPECIAL_CHARS | 針對 HTML 做 encoding,例如 < 會轉成 < |
FILTER_SANITIZE_EMAIL | 過濾不屬於 e-mail 的非法字元,例如 a(b)@gmail.com 會被過濾成 ab@gmail.com |
FILTER_SANITIZE_URL | 過濾 URL,刪除 URL 格式的非法字元 |
FILTER_SANITIZE_NUMBER_INT | 允許數字與 +- 符號,其餘刪除 |
FILTER_SANITIZE_NUMBER_FLOAT | 允許數字和 +-.,eE ,其餘刪除 |
Usage
在使用處理 Input 相關的 Filter function 時,可以搭配以下常數來決定處理的 Input 類型: Type Name |
Description |
---|---|
INPUT_GET | $_GET |
INPUT_POST | $_POST |
INPUT_COOKIE | $_COOKIE |
INPUT_SERVER | $_SERVER |
INPUT_ENV | $_ENV |
處理 Input 變數
// main.php?test=xxx
// 檢查 $_GET['test'] 變數是否存在
filter_has_var(INPUT_GET, 'test') ? 'Yes' : 'No';
// 將 $_GET['test'] 變數內的字串做 `HTML encoding` ,並去除 ASCII 碼在 32 以下(如空白)的字元
filter_input(INPUT_GET, 'test', FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_STRIP_HIGH);
定義不同條件過濾 Input 變數
/*
URL:http://www.test.com?url=blog++.johnsonlu.org&product_id=15&version=2.0.33
$_GET = [
'url' => 'blog++.johnsonlu.org',
'product_id' => '15',
'version' => '2.0.33'
];
OUTPUT:
[
'url' => 'blog%20%20.johnsonlu.org',
'product_id' => ,
'version' => '2.0.33'
]
*/
// 可以透過 filter、flags、options 來控制規則
$definition = [
// URL encode
'url' => FILTER_SANITIZE_ENCODED,
// 判斷值是否為 1 ~ 10 之間
'product_id' => [
'filter' => FILTER_VALIDATE_INT,
'options' => [
'min_range' => 1,
'max_range' => 10
]
],
// 允許數字和 +-.,eE,其餘刪除
'version' => [
'filter' => FILTER_SANITIZE_NUMBER_FLOAT,
'flags' => FILTER_FLAG_ALLOW_FRACTION
]
];
$arr = filter_input_array(INPUT_GET, $definition);
FILTER_CALLBACK
// OUTPUT:Hello my name is johnson!
$string = "Hello|my|name|is|johnson!";
echo filter_var($string, FILTER_CALLBACK, [
'options' => function ($string) {
return str_replace("|", " ", $string);
}
]);