views:

327

answers:

2

Hi, I am trying to do form validation by putting the post values into variables and those variables into an array and then cycling through them and outputting error messages for fields that are not filled in. I am having two issues. Firstly, the if statement is running for all the values even if the field is empty or is == to 'undefined' and secondly i don't know how to print out the actual name of a variable instead of the variable value. For example

$variable = 'hello';

print_x($variable)//prints 'variable' instead of 'hello'

I have tried two methods which are shown below.

   $error_message = "The following fields must be filled in:<br />";
        $fields_to_validate_arr = array($category,$producer,$product_name,$image_name,$description,$stock_quantity,$min_sale);
        foreach($fields_to_validate_arr as $v){
         if(empty($v) || $v = 'undefined'){//using variable bariables
          //increment the error message with a custom error message. 
          $error_message .= "->" . ucwords(str_replace('_',' ',$v)) . "<br />";//no need to use variable variables
         }
        }

And a different method where i use variable variables

$error_message = "The following fields must be filled in:<br />";
    $fields_to_validate_arr = array('category','producer','product_name','image_name','description','stock_quantity','min_sale');
    foreach($fields_to_validate_arr as $v){
     if(empty($$v) || $$v = 'undefined'){//using variable bariables
      //increment the error message with a custom error message. 
      $error_message .= "->" . ucwords(str_replace('_',' ',$v)) . "<br />";//no need to use variable variables
     }
    }

The variables are assigned further up in my code like

$category = myescape_function($_POST['category']);

Thanks

+1  A: 

As far as your first code block goes you have a bug in your IF statement. You were setting $v = 'undefined' which would evaluate to true every single time. You need to use the equality operator for the IF statement.

   $error_message = "The following fields must be filled in:<br />";
   $fields_to_validate_arr = array($category,$producer,$product_name,$image_name,$description,$stock_quantity,$min_sale);
   foreach($fields_to_validate_arr as $v){
       if(empty($v)){ //using variable variables
           //increment the error message with a custom error message. 
           $error_message .= "->" . ucwords(str_replace('_',' ',$v)) . "<br />";//no need to use variable variables
       }
   }
cballou
I can't see them, what are they?
andrew
Oh im missing the ==
andrew
@andrew - edited with explanation
cballou
fixing that first bug fixed it when the value is equal to 'undefined' but i still get an error response when the variable is empty. Should i use $v=='';? it there a difference?
andrew
You should really only need to do a check on empty($v) and you can remove the second check. Empty handles both cases of isset() and != '' so you don't need a secondary check.
cballou
@andrew: note that, in languages that use `=` for assignment, you can prevent the above bug by always putting the variable after the comparison operator. `'undefined' = $v` is invalid and will generate an error, indirectly alerting you to the fact you have a typo.
outis
+1  A: 

There's no need to create your own input variable array, since you already have $_POST:

$_POST = array_map('myescape_function', $_POST);
foreach($fields_to_validate_arr as $v){
    if(empty($_POST[$v]) || $_POST[$v] == 'undefined'){
       //increment the error message with a custom error message. 
       $error_message .= "->" . ucwords(str_replace('_',' ',$v)) . "<br />";
    }
}

Since the values aren't stored in separate variables, the problem of printing a variable's name rather than it's value goes away.

If you want to get really fancy, you can add support for custom validators:

function inputExists($name, &$source) {
    return !empty($source[$name]) && 'undefined' != $source[$name];
}
function inputIsNumeric($name, &$source) {
    return inputExists($name, $source) && is_numeric($source[$name]);
}
// checks for U.S. phone numbers only
function inputIsPhone($name, &$source) {
    if (inputExists($name, $source)) {
        // strip whatever non-numeric 
        $value = preg_replace('/[-.,() \t]+/', '', $source[$name]);
        return preg_match('^(1?[2-9]\d{2})?[2-9]\d{6}$', $value);
    }
    return False;
}
function inputMatchesRE($name, &$source, $RE) {
    return inputExists($name, $source) && preg_match($RE, $source[$name]);
}
function nameAndValidator($name, $validator) {
    if (function_exists($validator)) {
        return array('name' => $name, 'validator' => $validator, 'data' => '');
    } elseif (is_numeric($name)) {
        // if index is numeric, assume $validator actually holds the name
        return array('name' => $validator, 'validator' => 'inputExists', 'data' => '');
    } else {
        return array('name' => $name, 'validator' => 'inputMatchesRE', 'data' => $validator);
    }
}

$fields_to_validate_arr = array('name', 'street' => '/^\d+ +[a-z ]+(ave|st|wy|way|ln|lp|blvd)$/i', 'age'=> 'inputIsNumeric', 'phone' => 'inputIsPhone');

$_POST = array_map('myescape_function', $_POST);

foreach($fields_to_validate_arr as $name => $validator){
    list($name, $validator, $data) = nameAndValidator($name, $validator);
    if(! call_user_func($validator, $name, $_POST, $data)){
       //increment the error message with a custom error message. 
       $error_message .= "->" . ucwords(str_replace('_',' ',$v)) . "<br />";
    }
}
outis
Personally, I'd use ctype_digit or the like rather than is_numeric as is_numeric accepts scientific notation, hex and the like (which isn't what most people are looking for when validating a form).
preinheimer