Использование функции PHP Filter для проверки, но игнорирования пустых необязательных полей - PullRequest
6 голосов
/ 09 августа 2009

Я хочу использовать функции PHP Filter для быстрой фильтрации формы и отображения обратной связи для пользователя. Некоторые поля в моей форме являются обязательными, а некоторые нет.

Я собираюсь использовать filter_input_array() для фильтрации всех моих полей. Я передам данные через несколько прогонов. Таким образом, я смогу отображать несколько сообщений об ошибках.

У меня есть одна проблема: как я могу игнорировать пустые поля, которые не требуются? Я не видел фильтр для этого.

Обновление: разъяснение требований к фильтрам и сообщениям об ошибках:

Я хочу использовать фильтры для проверки:

  1. Если все обязательные поля заполнены
  2. Если дополнительные поля заполнены; если нет, игнорировать до конца процесса
  3. Если заполнены такие поля, как электронная почта, номер телефона и т. Д.

Я хочу отображать сообщения об ошибках для каждого типа ошибки, максимум 1 сообщение об ошибке на поле.

Ответы [ 3 ]

5 голосов
/ 09 августа 2009

Функции filter_xyz_array () будут возвращать NULL для элемента, который не существует во входном массиве, например,

<?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 для элемента переменной / массива, который содержит NULL. Вы можете использовать это для игнорирования элементов, которые установлены в NULL функциями фильтра.
В зависимости от того, что вы фильтруете, и структуры массива, возвращаемого функцией фильтра, вы можете даже использовать array_filter () для «очистки» массива.

3 голосов
/ 03 июня 2011

PHP-фильтры: Обработка необязательных значений / необязательных вводов формы с помощью функции фильтра filter_input_array ().

Я продемонстрирую простой способ обработки необязательных полей или входов форм при работе с фильтрами PHP. Практическое правило:

  1. Фильтр ВСЕ формы ввода, обязательные и дополнительные. Не оставляйте необязательные поля в вашем фильтре.
  2. Используйте оператор сравнения ===, чтобы различать значения 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>
2 голосов
/ 09 августа 2009

В итоге я использовал нестандартное решение, вдохновленное ответом @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
...