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 規則的屬性,通常還會再搭配 OptionsFilter Flags 建立額外的規則。

以下為幾個較為常用的 Filter Type:
Type Name
Description
FILTER_CALLBACK 可以自行定義 Filter 處理
FILTER_VALIDATE_INT 判斷數字是否有在範圍內
FILTER_VALIDATE_BOOLEAN 判斷布林值,1、 trueonyes 都會判斷成 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);
    }
]);
Categories: PHP