,在IBM DW的http://www.ibm.com/developerworks/cn/opensource/os-php-v522/index.html上有很好的介紹,下面筆記並補充之
過濾擴展功能有兩種過濾器:Sanitizing 和 Logical。
Sanitizing 過濾器只是允許或禁止字符串中的字符並將清理後的字符串作爲結果返回。無論您將哪種數據格式傳入這些函數,它們將始終返回字符串。對於特定類型的使用,這是至關重要的,因爲您可以阻止用戶發送不適當的輸入並導致異常結果。例如,用戶可以發現文本塊的輸入被返回到以下頁面上並且要利用那些返回信息。如果清理輸入,則將刪除輸入的所有危險部分。
Logical 過濾器將對變量執行測試並根據測試提供 true 或 false 結果。然後您可以使用結果來決定如何處理數據或獲得用戶的地址。這種過濾器的簡單示例是驗證年齡。邏輯測試還可以針對類似 Perl 的正則表達式進行測試。
<?php
echo "You are " . filter_var($_GET['1'], FILTER_SANITIZE_STRING) . ".<br>/n";
echo "Your favorite color is " . filter_var($_GET['2'], FILTER_SANITIZE_STRING) .
".<br>/n";
echo "The airspeed of an unladen swallow is " . filter_var($_GET['3'], FILTER_SANITIZE_STRING)
. ".<br>/n";
?>
用 filter_var()
函數來清理輸入並使其有效並且安全。在這種情況下,使用選項 FILTER_SANITIZE_STRING
,該選項將獲取輸入、刪除所有 HTML 標記並選擇性地編碼或刪除特定字符。
由於它將除去 HTML 標記,因此嘗試運行 JavaScript 將失敗,並且從腳本中獲得更適當的結果。
再補充些
PHP: indicates the earliest version of PHP that supports the function.
Function | Description | PHP |
---|---|---|
filter_has_var() | Checks if a variable of a specified input type exist | 5 |
filter_id() | Returns the ID number of a specified filter | 5 |
filter_input() | Get input from outside the script and filter it | 5 |
filter_input_array() | Get multiple inputs from outside the script and filters them | 5 |
filter_list() | Returns an array of all supported filters | 5 |
filter_var_array() | Get multiple variables and filter them | 5 |
filter_var() | Get a variable and filter it | 5 |
PHP Filters
ID Name | Description |
---|---|
FILTER_CALLBACK | Call a user-defined function to filter data |
FILTER_SANITIZE_STRING | Strip tags, optionally strip or encode special characters |
FILTER_SANITIZE_STRIPPED | Alias of "string" filter |
FILTER_SANITIZE_ENCODED | URL-encode string, optionally strip or encode special characters |
FILTER_SANITIZE_SPECIAL_CHARS | HTML-escape '"<>& and characters with ASCII value less than 32 |
FILTER_SANITIZE_EMAIL | Remove all characters, except letters, digits and !#$%&'*+-/=?^_`{|}~@.[] |
FILTER_SANITIZE_URL | Remove all characters, except letters, digits and $-_.+!*'(),{}|//^~[]`<>#%";/?:@&= |
FILTER_SANITIZE_NUMBER_INT | Remove all characters, except digits and +- |
FILTER_SANITIZE_NUMBER_FLOAT | Remove all characters, except digits, +- and optionally .,eE |
FILTER_SANITIZE_MAGIC_QUOTES | Apply addslashes() |
FILTER_UNSAFE_RAW | Do nothing, optionally strip or encode special characters |
FILTER_VALIDATE_INT | Validate value as integer, optionally from the specified range |
FILTER_VALIDATE_BOOLEAN | Return TRUE for "1", "true", "on" and "yes", FALSE for "0", "false", "off", "no", and "", NULL otherwise |
FILTER_VALIDATE_FLOAT | Validate value as float |
FILTER_VALIDATE_REGEXP | Validate value against regexp, a Perl-compatible regular expression |
FILTER_VALIDATE_URL | Validate value as URL, optionally with required components |
FILTER_VALIDATE_EMAIL | Validate value as e-mail |
FILTER_VALIDATE_IP | Validate value as IP address, optionally only IPv4 or IPv6 or not from private or reserved ranges |
檢測判斷的例子
1 | <html> |
2 | <head></head> |
3 | <body |
4 | <form action="example04.php" method="post" > |
5 | Enter your age: <input name="age" size="2"> |
6 | <input type="submit" name="submit" value="Go"> |
7 | </form> |
8 | </body> |
9 | </html> |
view plain | print | copy to clipboard | ? |
- <html>
- <head></head>
- <body
- <form action="example04.php" method="post" >
- Enter your age: <input name="age" size="2">
- <input type="submit" name="submit" value="Go">
- </form>
- </body>
- </html>
處理腳本:
1 | <?php |
2 | if (!filter_has_var(INPUT_POST, 'submit')) { |
3 | echo "form"; |
4 | // include the form. |
5 | } |
6 | |
7 | $age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT); |
8 | if (is_null($age)) { |
9 | echo "The 'age' field is required.<br />"; |
10 | } elseif ($age === FALSE) { |
11 | echo "Please enter a valid age.<br />"; |
12 | } else { |
13 | echo "Welcome.<br/>"; |
14 | } |
15 | ?> |
view plain | print | copy to clipboard | ? |
- <?php
- if (!filter_has_var(INPUT_POST, 'submit')) {
- echo "form";
- // include the form.
- }
- $age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT);
- if (is_null($age)) {
- echo "The 'age' field is required.<br />";
- } elseif ($age === FALSE) {
- echo "Please enter a valid age.<br />";
- } else {
- echo "Welcome.<br/>";
- }
- ?>
filter_has_var檢測給定的變量是否存在。它不會做任何處理只會告訴程序變量是否已經設置。相當於isset($_POST[‘submit’])。filter_input會取得一個變量返回處理好的數據。在上面的例子中會返回一個整數。
如果是要返回一個處於一定範圍之內的值,假設是7-77歲之間的人。可以指定一個最大值和一個最小值。
1 | <?php |
2 | if (!filter_has_var(INPUT_POST, 'submit')) { |
3 | echo "form"; |
4 | // include the form. |
5 | } |
6 | $options = array('options'=> array('min_range'=>7, 'min_range'=>77)); |
7 | $age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT, $options); |
8 | |
9 | if (is_null($age)) { |
10 | echo "The 'age' field is required.<br />"; |
11 | } elseif ($age === FALSE) { |
12 | echo "You must be enter a valid age and be between 7 and 77 years old.<br />"; |
13 | } else { |
14 | echo "Welcome.<br/>"; |
15 | } |
16 | ?> |
view plain | print | copy to clipboard | ? |
- <?php
- if (!filter_has_var(INPUT_POST, 'submit')) {
- echo "form";
- // include the form.
- }
- $options = array('options'=> array('min_range'=>7, 'min_range'=>77));
- $age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT, $options);
- if (is_null($age)) {
- echo "The 'age' field is required.<br />";
- } elseif ($age === FALSE) {
- echo "You must be enter a valid age and be between 7 and 77 years old.<br />";
- } else {
- echo "Welcome.<br/>";
- }
- ?>
如果是要判斷一個有效的郵件地址的話,可以這樣:
1 | $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL); |
view plain | print | copy to clipboard | ? |
- $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
如果郵件地址不正確或者是空的話$email的值將爲FALSE。
過濾判斷的例子
1 | <html> |
2 | <head></head> |
3 | <body> |
4 | <form action="example05.php" method="post" > |
5 | Enter your name: <input name="name" size="50"> |
6 | <input type="submit" name="submit" value="Go"> |
7 | </form> |
8 | </body> |
9 | </html> |
view plain | print | copy to clipboard | ? |
- <html>
- <head></head>
- <body>
- <form action="example05.php" method="post" >
- Enter your name: <input name="name" size="50">
- <input type="submit" name="submit" value="Go">
- </form>
- </body>
- </html>
下面的filter_input函數將自動過濾並返回適當的值:
1 | <?php |
2 | if (!filter_has_var(INPUT_POST, 'submit')) { |
3 | echo "form"; |
4 | // include the form. |
5 | } |
6 | $name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_SPECIAL_CHARS); |
7 | if (is_null($name)) { |
8 | echo "The 'name' field is required.<br />"; |
9 | } else { |
10 | echo "Hello $name.<br/>"; |
11 | } |
12 | ?> |
view plain | print | copy to clipboard | ? |
- <?php
- if (!filter_has_var(INPUT_POST, 'submit')) {
- echo "form";
- // include the form.
- }
- $name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_SPECIAL_CHARS);
- if (is_null($name)) {
- echo "The 'name' field is required.<br />";
- } else {
- echo "Hello $name.<br/>";
- }
- ?>
如果接收到的name值是:
Johnny Weißmüller <b>Jr</b>
FILTER_SANITIZE_SPECIAL_CHARS 將會返回:
Hello Johnny Weißmüller <b>Jr</b>.
一個更好的過濾寫法:
1 | $name = filter_input(INPUT_POST, |
2 | 'name', |
3 | FILTER_SANITIZE_STRING, |
4 | FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW); |
view plain | print | copy to clipboard | ? |
- $name = filter_input(INPUT_POST,
- 'name',
- FILTER_SANITIZE_STRING,
- FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW);
輸出:
Hello Johnny Weißmüller Jr.
這裏的函數還有很多選項,如果你想了解更多的細節可以查看Filter的文檔。
如何一次處理所有輸入?
1 | <html> |
2 | <head></head> |
3 | <body |
4 | <form action="example07.php" method="post" > |
5 | Name: <input name="name" size="50"><br /> |
6 | Email: <input name="email" size="50"><br /> |
7 | Homepage: <input name="homepage" size="50"><br /> |
8 | Age: <input name="age" size="4"><br /> |
9 | Income: <input name="income" size="50"><br /> |
10 | Your two favourites languages: |
11 | <select name="favourites[]" size="6" multiple> |
12 | <option value="haskell">haskell</option> |
13 | <option value="r">R</option> |
14 | <option value="lua">Lua</option> |
15 | <option value="pike">Pike</option> |
16 | <option value="rebol">Rebol</option> |
17 | <option value="php">PHP</option> |
18 | </select><br /> |
19 | <input type="submit" name="submit" value="Go"> |
20 | </form> |
21 | </body> |
22 | </html> |
view plain | print | copy to clipboard | ? |
- <html>
- <head></head>
- <body
- <form action="example07.php" method="post" >
- Name: <input name="name" size="50"><br />
- Email: <input name="email" size="50"><br />
- Homepage: <input name="homepage" size="50"><br />
- Age: <input name="age" size="4"><br />
- Income: <input name="income" size="50"><br />
- Your two favourites languages:
- <select name="favourites[]" size="6" multiple>
- <option value="haskell">haskell</option>
- <option value="r">R</option>
- <option value="lua">Lua</option>
- <option value="pike">Pike</option>
- <option value="rebol">Rebol</option>
- <option value="php">PHP</option>
- </select><br />
- <input type="submit" name="submit" value="Go">
- </form>
- </body>
- </html>
處理程序:
1 | <?php |
2 | if (!filter_has_var(INPUT_POST, 'submit')) { |
3 | echo "form"; |
4 | // include the form. |
5 | } |
6 | |
7 | $defs = array( |
8 | 'name' => array('filter'=>FILTER_SANITIZE_STRING, |
9 | 'flags' => FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW), |
10 | 'email' => FILTER_VALIDATE_EMAIL, |
11 | 'homepage' => FILTER_VALIDATE_URL, |
12 | 'age' => array( 'filter' => FILTER_VALIDATE_INT, |
13 | 'options'=> array('min_range'=>7, 'min_range'=>77)), |
14 | 'income' => FILTER_VALIDATE_FLOAT, |
15 | 'favourites' => array( |
16 | 'filter' => FILTER_SANITIZE_STRING, |
17 | 'flags' => FILTER_REQUIRE_ARRAY |
18 | ), |
19 | ); |
20 | |
21 | $input = filter_input_array(INPUT_POST, $defs); |
22 | |
23 | if ($input['age'] === FALSE) { |
24 | exit("You must be between 7 and 77 years old."); |
25 | } |
26 | |
27 | if (is_null($input['favourites'])) { |
28 | exit("You have to choose two or more languages."); |
29 | } |
30 | |
31 | if (!in_array('PHP', $inputs['favourites'])) { |
32 | exit("You don't like PHP!"); |
33 | } |
34 | |
35 | /*Other checks for required values */ |
36 | ?> |
view plain | print | copy to clipboard | ? |
- <?php
- if (!filter_has_var(INPUT_POST, 'submit')) {
- echo "form";
- // include the form.
- }
- $defs = array(
- 'name' => array('filter'=>FILTER_SANITIZE_STRING,
- 'flags' => FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW),
- 'email' => FILTER_VALIDATE_EMAIL,
- 'homepage' => FILTER_VALIDATE_URL,
- 'age' => array( 'filter' => FILTER_VALIDATE_INT,
- 'options'=> array('min_range'=>7, 'min_range'=>77)),
- 'income' => FILTER_VALIDATE_FLOAT,
- 'favourites' => array(
- 'filter' => FILTER_SANITIZE_STRING,
- 'flags' => FILTER_REQUIRE_ARRAY
- ),
- );
- $input = filter_input_array(INPUT_POST, $defs);
- if ($input['age'] === FALSE) {
- exit("You must be between 7 and 77 years old.");
- }
- if (is_null($input['favourites'])) {
- exit("You have to choose two or more languages.");
- }
- if (!in_array('PHP', $inputs['favourites'])) {
- exit("You don't like PHP!");
- }
- /*Other checks for required values */
- ?>
正如上面例子中的,通過一個函數就能處理所有的變量。唯一不同的就是事先定義一個對應的數組。需要注意的是數組中選項的正確性。
這樣的做法不但增加了程序的易讀性,並且如果要添加移除或者修改處理規則也會非常方便。
更復雜的處理
在下面的處理“favourites”變量時用到了用戶自定義函數。"options"指定一個用戶自定義函數通過定義callback來實現,語法和PHP的call_user_func一樣。
1 | <?php |
2 | class language { |
3 | function __construct($name) { |
4 | $this->name = $name; |
5 | } |
6 | } |
7 | |
8 | function check_languages($var) { |
9 | static $called = 0; |
10 | $called++; |
11 | echo "called: $called: $var<br />"; |
12 | $var = filter_var($var, FILTER_SANITIZE_STRIPPED); |
13 | $l = new language($var); |
14 | return $l; |
15 | } |
16 | |
17 | if (!filter_has_var(INPUT_POST, 'submit')) { |
18 | echo "form"; |
19 | // include the form. |
20 | } |
21 | |
22 | $defs = array( |
23 | 'name' => array('filter'=>FILTER_SANITIZE_STRING, |
24 | 'flags' => FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW), |
25 | 'email' => FILTER_VALIDATE_EMAIL, |
26 | 'homepage' => FILTER_VALIDATE_URL, |
27 | 'age' => FILTER_VALIDATE_INT, |
28 | 'income' => FILTER_VALIDATE_FLOAT, |
29 | 'favourites' => array( |
30 | 'filter' => FILTER_CALLBACK, |
31 | 'options' => 'check_languages' |
32 | ), |
33 | ); |
34 | |
35 | $input = filter_input_array(INPUT_POST, $defs); |
36 | |
37 | if ($input['age'] === FALSE) { |
38 | exit("You must be between 7 and 77 years old."); |
39 | } |
40 | |
41 | if (is_null($input['favourites'])) { |
42 | exit("You have to choose two or more languages."); |
43 | } |
44 | |
45 | echo "Your favourite languages:<br /><ul>"; |
46 | foreach ($input['favourites'] as $l) echo '<li>' . $l->name . "</li>"; |
47 | echo '</ul>'; |
48 | ?> |
view plain | print | copy to clipboard | ? |
- <?php
- class language {
- function __construct($name) {
- $this->name = $name;
- }
- }
- function check_languages($var) {
- static $called = 0;
- $called++;
- echo "called: $called: $var<br />";
- $var = filter_var($var, FILTER_SANITIZE_STRIPPED);
- $l = new language($var);
- return $l;
- }
- if (!filter_has_var(INPUT_POST, 'submit')) {
- echo "form";
- // include the form.
- }
- $defs = array(
- 'name' => array('filter'=>FILTER_SANITIZE_STRING,
- 'flags' => FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW),
- 'email' => FILTER_VALIDATE_EMAIL,
- 'homepage' => FILTER_VALIDATE_URL,
- 'age' => FILTER_VALIDATE_INT,
- 'income' => FILTER_VALIDATE_FLOAT,
- 'favourites' => array(
- 'filter' => FILTER_CALLBACK,
- 'options' => 'check_languages'
- ),
- );
- $input = filter_input_array(INPUT_POST, $defs);
- if ($input['age'] === FALSE) {
- exit("You must be between 7 and 77 years old.");
- }
- if (is_null($input['favourites'])) {
- exit("You have to choose two or more languages.");
- }
- echo "Your favourite languages:<br /><ul>";
- foreach ($input['favourites'] as $l) echo '<li>' . $l->name . "</li>";
- echo '</ul>';
- ?>
如果參數是標準參數,函數將只會別調用一次,如果變量是一個數組,將會自動被數組的每個成員調用一次。
當使用callback的時候Filter不會轉換或者驗證輸入數據。但是上面例子中的filter_var可以在callback函數或者方法中使用。