代码之家  ›  专栏  ›  技术社区  ›  Scharrels

使用php filter函数进行验证,但忽略空的非必需字段

  •  6
  • Scharrels  · 技术社区  · 15 年前

    我想用 PHP Filter 函数可以快速筛选表单并向用户显示反馈。我表单中的某些字段是必需的,而有些则不是。

    我要用 filter_input_array() 过滤所有字段。我将在多次运行中传递数据。这样,我就可以显示多条错误消息。

    我有一个问题:如何忽略不需要的空字段?我没有看到过滤器。

    更新:澄清过滤器和错误消息的要求:

    我想使用过滤器检查:

    1. 如果填写了所有必需字段
    2. 如果填写了可选字段,则忽略该过程的其余部分。
    3. 如果填写了电子邮件、电话号码等字段。

    我想为每种类型的错误显示错误消息,每个字段最多显示一条错误消息。

    3 回复  |  直到 13 年前
        1
  •  5
  •   VolkerK    15 年前

    filter_xyz_array()函数将为输入数组中不存在的元素返回空值,例如

    <?php
    
    $args = array(
        'foo'    => array(
            'filter'    => FILTER_VALIDATE_INT,
            'flags'     => FILTER_REQUIRE_ARRAY,
            'options'   => array('min_range' => 1, 'max_range' => 4)
        ),
        'bar'   => array(
            'filter' => FILTER_VALIDATE_INT,
            'flags'  => FILTER_REQUIRE_SCALAR
        )
    );
    
    $input = array(
        'foo'=>array(1,2,3,4)
    );
    
    $filtered = filter_var_array($input, $args);
    var_dump($filtered);
    

    印刷品

    array(2) {
      ["foo"]=>
      array(4) {
        [0]=>
        int(1)
        [1]=>
        int(2)
        [2]=>
        int(3)
        [3]=>
        int(4)
      }
      ["bar"]=>
      NULL
    }
    

    isset() 对于包含空值的变量/数组元素,返回false。你可以用它 忽视 由筛选函数设置为空的元素。
    取决于您过滤的内容和过滤器函数返回的数组结构,您甚至可以使用 array_filter() “清理”阵列。

        2
  •  3
  •   Alphonse    13 年前

    php过滤器:使用filter_input_array()过滤器函数处理可选值/可选表单输入。

    我将演示在使用PHP过滤器时如何处理可选字段或表单输入的简单方法。经验法则是:

    1. 筛选所有表单输入,必需和可选。不要漏掉过滤器中的可选字段。
    2. 使用==Comparison运算符区分false、null和0值

    下面显示了具有4个必需输入和4个可选输入的简单联系人表单的示例代码

    <?php
    if ($_SERVER["REQUEST_METHOD"] == "POST"){
    /*set validation control variable*/
    $input_error_flag = true;
    
    /*set form input validation filters*/
    $form_filter = array(
        'first_name'        =>  FILTER_SANITIZE_STRING,
        'middle_name'       =>  FILTER_SANITIZE_STRING,
        'last_name'         =>  FILTER_SANITIZE_STRING,
        'email_address'     =>  FILTER_SANITIZE_EMAIL,
        'postal_address'    =>  FILTER_SANITIZE_NUMBER_INT,
        'street_address'    =>  FILTER_SANITIZE_STRING,
        'telephone_number'  =>  FILTER_SANITIZE_NUMBER_INT,
        'mobile_number'     =>  FILTER_SANITIZE_NUMBER_INT,
    );
    
    /*list optional fields or optional form inputs in array*/
    $optional_fields = array(
        'middle_name'       => "",  'postal_address'    => "",
        'street_address'    => "",  'mobile_number'     => "",
        );
    
    /*set error display message of each required element*/
    $error_description = array(
        'first_name'        =>"Missing or incorrect First Name",
        'last_name'         =>"Missing or incorrect Last Name",
        'email_address'     =>"Missing or incorrect Email Address",
        'telephone_number'  =>"Missing or incorrect Telephone Number",
        );
    
    /*sanitize all form inputs against form_filter*/
    $form_data = filter_input_array(INPUT_POST, $form_filter);
    
    /*check form inputs for filter validation errors*/
    foreach ($form_data as $form_input => $value){
        /*check if filter failed (false), input not defined (null) or input missing ("")
        * and insert name of form input element into $invalid_array for error display
        */
        if($value === FALSE || $value === NULL || $value == ""){
            /*exclude error display for optional items with empty values*/
            if(!(array_key_exists($form_input, $optional_fields) && $value == "")){
                $invalid_inputs[] = $form_input;
            }
        }
    }
    
    /*unset filter validation control variable if no errors*/
    if(empty ($invalid_inputs))
                    $input_error_flag = false;
    
    /*your calls to SQL functions for INSERT or UPDATE statements go here*/
    if(!$input_error_flag){
        functionname::getInstance()->insert_contact_details($form_data);
    }
    }
    ?>
    

    最后是带有错误显示部分的HTML表单

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      </head>
      <body>
        <form action="sample.php" method="POST" id="sample">
        <label for="first_name">First Name*</label>
        <input type="text" name="first_name" id="first_name"
               value="<?php echo $form_data['first_name']; ?>"/><br/>
        <label for="middle_name">Middle Name</label>
        <input type="text" name="middle_name" id="middle_name"
               value="<?php echo $form_data['middle_name']; ?>"/><br/>
        <label for="last_name">Last Name*</label>
        <input type="text" name="last_name" id="last_name"
               value="<?php echo $form_data['last_name']; ?>"/><br/>
        <label for="email_address">Email Address*</label>
        <input type="text" name="email_address" id="email_address"
               value="<?php echo $form_data['email_address']; ?>"/><br/>
        <label for="postal_address">Postal Address</label>
        <input type="text" name="postal_address" id="postal_address"
               value="<?php echo $form_data['postal_address']; ?>"/><br/>
        <label for="street_address">Street Address</label>
        <input type="text" name="street_address" id="street_address"
               value="<?php echo $form_data['street_address']; ?>"/><br/>
        <label for="telephone_number">Telephone Number*</label>
        <input type="text" name="telephone_number" id="telephone_number"
               value="<?php echo $form_data['telephone_number']; ?>"/><br/>
        <label for="mobile_number">Mobile Number</label>
        <input type="text" name="mobile_number" id="mobile_number"
               value="<?php echo $form_data['mobile_number']; ?>"/><br/>
        <input type="submit" name="submit" value="submit"><br/>
            <?php
                //display input validation errors on your html form
                if ($input_error_flag){
                    foreach($invalid_inputs as $key => $form_input){
                        if(array_key_exists($form_input, $error_description)){
                            echo $error_description[$form_input]."<br/>";
                        }
                    }
                }
            ?>
        </form>
      </body>
    </html>
    
        3
  •  2
  •   Scharrels    14 年前

    我最终使用了一个定制的解决方案,灵感来自于@volkerk的回答。我应该说得更清楚我想要什么。我已经用这些信息更新了我的问题。

    我仍在寻找更简单的解决方案。

    首先,我做了一些结果数组:

    // errors to display
    $errors = array();
    // fields to ignore in the validation step
    $ignore_fields = array();
    // return values after validation
    $returnvalues = array();
    

    我首先筛选了所需字段:

    function required($string){
    return trim($string) == "" ? false : $string;
    }
    
    $required_errors = array(
      "firstname" => "Je moet je voornaam invullen.", 
      "lastname" => "Je moet je achternaam invullen.", 
      "email" => "Je moet je e-mailadres invullen."
    );
    
    $required_filter = array();
      foreach($required_errors as $requiredfieldname => $error){
        $required_filter[$requiredfieldname] = array(
          'filter' => FILTER_CALLBACK,
          'options' => "required",
          'flags' => FILTER_NULL_ON_FAILURE
        ); 
    }
    
    $required_filtered = filter_input_array(INPUT_GET | INPUT_POST, 
         $required_filter);
    
    foreach($required_errors as $required => $error){      
      if(!isset($required_filtered[$required])){
        $errors[$required] = $required_errors[$required];
        $returnvalues[$required] = "";
        $ignore_fields[$required] = "ignored"; // value doesn't matter
      }
    }
    

    然后检查空字段并用标准值加载它们

    // ignore the other fields if they are empty;
    // the actual form has about 10 values here
    $maybeempty = array("from", "to", "phonenumber"); 
    
    $optional_defaultvalue = array(
      "from" => 0,
      "to" => 0,
      "phonenumber" => "",
    );
    
    $optional_filter = array();
    foreach($maybeempty as $field){
      $required_filter[$requiredfieldname] = array(
        'filter' => FILTER_CALLBACK,
        'options' => "required",
        'flags' => FILTER_NULL_ON_FAILURE
      ); 
    }
    
    $optional_filtered = filter_input_array(INPUT_GET | INPUT_POST, 
        $required_filter);
    foreach($maybeempty as $field){
      if(!isset($optional_filtered[$field])){
        $ignore_fields[$field] = "ignored"; // value doesn't matter
        $returnvalue[$field] = $optional_defaultvalue[$field];
      }
    }
    

    在最后一步中,我将构建一个验证数组、自定义错误消息并忽略忽略忽略字段,以跳过空字段或已经有错误的字段:

     $validity_filter = array(
         'email' => array(
           'filter' => FILTER_VALIDATE_EMAIL, 
           'flags' => FILTER_REQUIRE_SCALAR
         ),
         'from' => array(
           'filter' => FILTER_VALIDATE_INT,
           'flags' => FILTER_REQUIRE_SCALAR,
           'options' => array('min_range' => 1964, 'max_range' => 2009)),
         'to' => array(
            'filter' => FILTER_VALIDATE_INT,
            'flags' => FILTER_REQUIRE_SCALAR,
            'options' => array('min_range' => 1964, 'max_range' => 2009))
     );
    
     // filter all ignored fields
     $validity_filter = array_diff_key($validity_filter, $ignore_fields);
     $validity_filtered = filter_input_array(INPUT_GET | INPUT_POST, 
         $required_filter);
    
     foreach($validity_filter as $field => $value){
       if($value === false){ // NULL values are checked in a previous step
         $errors[$field] = $validity_errors[$field]; // show error
         $returnvalues[$field] = $_REQUEST[$field]; // return original value
       } else {
         $returnvalues[$field] = $value; // return filtered value
       }
     }
    
     // process possible errors and response values