使用 PHP 過濾器(Filter)進行嚴格表單驗證

PHP 過濾器(Filter)用於驗證和過濾來自非安全來源的數據,好比用戶的輸入,使用過濾器擴展能夠使數據過濾更輕鬆快捷。要求的 PHP 版本是 PHP 5 >= 5.2.0,PHP 7javascript

 

和 Filter 有關的函數包括php

filter_has_var 檢測接收指定類型的變量是否存在,例如經過post傳遞的username變量是否存在
filter_id — 返回與某個特定名稱的過濾器相關聯的id
filter_input_array — 獲取一系列外部變量,而且能夠經過過濾器處理它們
filter_input — 經過名稱獲取特定的外部變量,而且能夠經過過濾器處理它
filter_list — 返回所支持的過濾器列表
filter_var_array — 獲取多個變量而且過濾它們
filter_var — 使用特定的過濾器過濾一個變量

其中html

filter_input(int $type, string $variable_name [, int $filter = FILTER_DEFAULT] [, mixed $options])java

參數 $type 能夠是 INPUT_GET,INPUT_POST,INPUT_COOKIE,INPUT_SERVER 或 INPUT_ENV數組

參數 $filter 的類型能夠參見 php 手冊:http://php.net/manual/zh/filter.filters.php安全

 

使用 Filter 能夠對錶單必填域驗證、數字驗證、email 驗證、下拉菜單驗證、單選按鈕驗證、複選框驗證等。函數

使用 Filter 能夠節省不少正則,例如驗證 email、INT、bool ,而且 filter_has_var 函數比 isset 函數要更快。post

 

1、驗證必填域編碼

//檢查$_POST['username']長度以前首先確保它存在
if(! (filter_has_var(INPUT_POST, 'username') && (strlen(filter_input(INPUT_POST, 'username')) > 0) )) {
    echo '請輸入用戶名';
    exit;
}

說明:filter_has_var 函數在接收到了變量時對變量的值進行驗證,在該例中,若是接受到了 $_POST['username'] ,即對 $_POST['username'] 的值進行驗證,若是沒有接收到變量 $_POST['username'],例如該字段在表單中是單個的複選框,不勾選的話,處理的頁面是接收不到該字段的信息的。spa

 

2、驗證長度

//FILTER_SANITIZE_STRING過濾器會去除HTML標記、刪除二進制非ASCII字符、並對與字符編碼(&)
if(filter_has_var(INPUT_POST, 'country') && strlen(filter_input(INPUT_POST, 'country', FILTER_SANITIZE_STRING)) <=2) {
    echo 'country長度不小於2個字符';
    exit;
}

說明:

參數 FILTER_SANITIZE_STRING 用於去除 HTML 標記、刪除二進制非 ASCII 字符、而且對與字符編碼(&)

 

3、驗證郵箱

//驗證郵箱
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if($email === false) {
    echo '請輸入正確的郵箱';
    exit;
}

說明:使用參數 FILTER_VALIDATE_EMAIL 驗證 email

 

4、驗證整數

//驗證整數,若是填寫了年齡則進行驗證
if(strlen(filter_input(INPUT_POST, 'age')) > 0) {
    $age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT);
    if($age === false) {
        echo '請輸入正確的年齡';
        exit;
    }
}

說明:使用參數FILTER_VALIDATE_INT  驗證整數

 

5、驗證小數

//驗證小數,若是填寫了salary則進行驗證
if(strlen(filter_input(INPUT_POST, 'salary')) > 0) {
    $salary = filter_input(INPUT_POST, 'salary', FILTER_VALIDATE_FLOAT);
    if($salary === false) {
        echo '請輸入正確的薪資';
        exit;
    }
}

說明:使用參數 FILTER_VALIDATE_FLOAT 驗證浮點數

 

6、驗證數組,複選框驗證組

//確保$_POST['sports']存在且是一個數組
if(! (filter_has_var(INPUT_POST, 'sports') && filter_input(INPUT_POST, 'sports', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY))) {
    echo '請選擇一項運動';
    exit;
}

//驗證複選框組
//array_intersect 計算數組的交集
if(array_intersect($_POST['sports'], array_values($sports)) != $_POST['sports']) {
    echo '請選擇正確的運動';
    exit;
}

說明:使用參數 FILTER_DEFAULT 進行佔位,使用參數 FILTER_REQUIRE_ARRAY 驗證是不是數組

使用 array_intersect 函數計算數組的交集

 

7、驗證單個複選框

//驗證單個複選框
if(filter_has_var(INPUT_POST, 'single')) { 
    if($_POST['single'] == $value) {
        $single = true;
    } else {
        $single = false;
        echo '錯誤的提交';
        exit;
    }
}

 

8、驗證下拉菜單

//驗證下拉菜單
if(! (filter_has_var(INPUT_POST, 'food') && array_key_exists($_POST['food'], $choices))) {
    echo '請選擇喜歡的食物';
    exit;
}

 

9、驗證單選按鈕

//驗證性別
if(! (filter_has_var(INPUT_POST, 'sex') && in_array($_POST['sex'], $sex))) {
    echo '請選擇性別';
    exit;
}

 

10、驗證時間

//驗證時間
if(filter_has_var(INPUT_POST, 'time')) {
    foreach($_POST['time'] as $time) {
        @list($year, $month, $day) = explode('-', $time);
        if(! @checkdate($month, $day, $year)) {
            echo '時間錯誤';
            exit;
        }
        //時間段驗證(略)
    }
}

說明:使用 checkdate 函數驗證是不是正確的時間

 

完整代碼:

<?php
    
    header('Content-type:text/html;charset=utf-8');

    //下拉菜單 value=>choice
    $choices = ['Eggs'=>'Eggs Benedict', 'toast'=>'Buttered Toast with jam', 'coffee'=>'piping hot coffee'];
    //單選按鈕 choice=>value
    $sex = ['male'=>1, 'femail'=>2];
    $defaults['sex'] = 'male';
    //單個複選框
    $value = 'yes';
    //複選框組 choice=>value
    $sports = ['足球'=>'football', '跑步'=>'run', '壁球'=>'wall_ball'];

    if($_SERVER['REQUEST_METHOD'] == 'GET') {
?>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <script language="javascript" type="text/javascript" src="My97DatePicker/WdatePicker.js"></script>
    </head>
    <body>
        <form action="<?php echo htmlentities($_SERVER['SCRIPT_NAME']);?>" method="post">
            <table>
                <tr>
                    <td>name:</td>
                    <td><input type="text" name="username"></td>
                </tr>
                <tr>
                    <td>country:</td>
                    <td><input type="text" name="country"></td>
                </tr>                
                <tr>
                    <td>email:</td>
                    <td><input type="text" name="email"></td>
                </tr>
                <tr>
                    <td>age:</td>
                    <td>
                        <input type="text" name="age">
                    </td>
                </tr>
                <tr>
                    <td>salary:</td>
                    <td>
                        <input type="text" name="salary">
                    </td>
                </tr>                
                <tr>
                    <td>food:</td>
                    <td>
                        <?php echo "<select name='food'>\n";
                            echo "<option value='0'>請選擇喜歡的食物:</option>\n";
                            foreach($choices as $key=>$choice) {
                                echo "<option value='".$key."'>".$choice."</option>\n";
                            }
                            echo "</select>";
                        ?>
                    </td>
                </tr>
                <tr>
                    <td>sex:</td>
                    <td>
                        <?php
                            foreach($sex as $key=>$choice) {
                                echo "<input type='radio' name='sex' value='".$choice."'";
                                if($defaults['sex'] == $key) {
                                    echo "checked='checked'";
                                }
                                echo ">".$key."\n";
                            }
                        ?>
                    </td>
                </tr>    
                <tr>
                    <td colspan="2">
                        <?php
                        foreach($sports as $key=>$choice) {
                            echo "<input type='checkbox' name='sports[]' value='".$choice."'>".$key."\n";
                        }
                        ?>
                    </td>
                </tr>        
                <tr>
                    <td>
                        是否單身:
                    </td>
                    <td>
                        <?php
                            echo "<input type='checkbox' name='single' value='yes'>";
                        ?>
                    </td>
                </tr>    
                <tr>
                    <td>
                        工做起始時間:
                    </td>
                    <td>
                        <input class="Wdate" type="text" name="time[]" onClick="WdatePicker()"><input class="Wdate" type="text" name="time[]" onClick="WdatePicker()">
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                        <input type="submit" value="提交">
                    </td>
                </tr>
            </table>
        </form>
    </body>
    </html>
<?php
    } else {
        //嚴格表單認證
        //檢查$_POST['username']長度以前首先確保它存在
        if(! (filter_has_var(INPUT_POST, 'username') && (strlen(filter_input(INPUT_POST, 'username')) > 0) )) {
            echo '請輸入用戶名';
            exit;
        }

        //$_POST['country']是可選的,不過若是提供了country字段,則保證在處理後要多於5個字符
        //FILTER_SANITIZE_STRING過濾器會去除HTML標記、刪除二進制非ASCII字符、並對與字符編碼(&)
        if(filter_has_var(INPUT_POST, 'country') && strlen(filter_input(INPUT_POST, 'country', FILTER_SANITIZE_STRING)) <=2) {
            echo 'country長度不小於2個字符';
            exit;
        }

        //驗證郵箱
        $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
        if($email === false) {
            echo '請輸入正確的郵箱';
            exit;
        }

        //確保$_POST['sports']存在且是一個數組
        if(! (filter_has_var(INPUT_POST, 'sports') && filter_input(INPUT_POST, 'sports', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY))) {
            echo '請選擇一項運動';
            exit;
        }

        //驗證複選框組
        //array_intersect 計算數組的交集
        if(array_intersect($_POST['sports'], array_values($sports)) != $_POST['sports']) {
            echo '請選擇正確的運動';
            exit;
        }

        //驗證單個複選框
        if(filter_has_var(INPUT_POST, 'single')) { 
            if($_POST['single'] == $value) {
                $single = true;
            } else {
                $single = false;
                echo '錯誤的提交';
                exit;
            }
        }

        //驗證整數,若是填寫了年齡則進行驗證
        if(strlen(filter_input(INPUT_POST, 'age')) > 0) {
            $age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT);
            if($age === false) {
                echo '請輸入正確的年齡';
                exit;
            }
        }

        //驗證小數,若是填寫了salary則進行驗證
        if(strlen(filter_input(INPUT_POST, 'salary')) > 0) {
            $salary = filter_input(INPUT_POST, 'salary', FILTER_VALIDATE_FLOAT);
            if($salary === false) {
                echo '請輸入正確的薪資';
                exit;
            }
        }

        //驗證下拉菜單
        if(! (filter_has_var(INPUT_POST, 'food') && array_key_exists($_POST['food'], $choices))) {
            echo '請選擇喜歡的食物';
            exit;
        }

        //驗證性別
        if(! (filter_has_var(INPUT_POST, 'sex') && in_array($_POST['sex'], $sex))) {
            echo '請選擇性別';
            exit;
        }

        //驗證時間
        if(filter_has_var(INPUT_POST, 'time')) {
            foreach($_POST['time'] as $time) {
                @list($year, $month, $day) = explode('-', $time);
                if(! @checkdate($month, $day, $year)) {
                    echo '時間錯誤';
                    exit;
                }
                //時間段驗證(略)
            }
        }

        echo 'Hello, ',$_POST['username'];
        var_dump($_POST);
    }
?>

 

 

參考:

<PHP Cookbook>,3rd

php.net:http://php.net/manual/zh/book.filter.php

w3school:http://www.w3school.com.cn/php/php_filter.asp

相關文章
相關標籤/搜索