0

I'm getting: 3 warnings (Illegal offset type in isset or empty in...) 3 notice (Undefined index: ...)

The 3 warnings are realated with the first foreach. And the 3 notices are related with the second foreach loop.

I don't really get what I'm doing wrong... Need some help out here.

<form name="form" action="index.php" method="POST">
    <input type="text" name="name" value="<?php if (isset($_POST['name'])) { echo $_POST['name']; } ?>" />
    <input type="text" name="age" value="<?php if (isset($_POST['age'])) { echo $_POST['age']; } ?>" />
    <input type="text" name="email" value="<?php if (isset($_POST['email'])) { echo $_POST['email']; } ?>" />
    <input type="submit" />
</form>

<?php
$expected = array(
    'name' => array("filter" => FILTER_SANITIZE_STRING),
    'age' => array("filter" => FILTER_SANITIZE_NUMBER_INT),
    'email' => array("filter" => FILTER_SANITIZE_EMAIL)
);

foreach ($expected AS $key => $value) {
    if (!isset($_POST[$value])) {
        echo "not set";
    } elseif (empty($_POST[$value])) {
        echo "empty";
    }
}

$result = filter_input_array(INPUT_POST, $expected);

foreach ($result AS $key => $value) {
    if (!$result[$value]) {
        echo "not valid value";
    }
}
?>

Thank you all.

6
  • What’s the wrong result, and what did you expect? Commented Dec 26, 2012 at 19:25
  • In the foreach, why do you expect $key to be both a value and a key? Commented Dec 26, 2012 at 19:28
  • I expect to loop through the array in the first foreach and verify if $_POST indexes are empty/null before assign values to $expected array indexes... if success I want to assing values and verify if are valid. Commented Dec 26, 2012 at 19:56
  • $_POST[$value] and $result[$value] are key lookups, but you are looking for a key with a value of $value when what you probably want is $_POST[$key]. Commented Dec 26, 2012 at 20:09
  • I know I've updated my code anyway, I can't get it to work! I guess what you meen is: foreach($expected AS $key){ if (!isset($_POST($key)))... Commented Dec 26, 2012 at 20:11

1 Answer 1

2

The forms of foreach are foreach($iterable as $value) and foreach($iterable as $key => $value). There is no foreach ($iterable as $key) form as with javascript's for (key in obj).

Instead use foreach ($expected as $key => $value) { and foreach($result as $key=>$value) { if (!$value) die(false); }

Your complete code should be something like this:

$expected = array(
    'name' => array("filter" => FILTER_SANITIZE_STRING),
    'age' => array("filter" => FILTER_SANITIZE_NUMBER_INT),
    'email' => array("filter" => FILTER_SANITIZE_EMAIL)
);

foreach ($expected AS $key => $value) {
    if (!isset($_POST[$key])) {  // NOT $value!!!!
        echo "not set";
    } elseif (empty($_POST[$key])) {
        echo "empty";
    }
}

$result = filter_input_array(INPUT_POST, $expected);

foreach ($result AS $key => $value) {
    if (!$result[$key]) {  // NOT $value!!!
        echo "not valid value";
    }
}

If your goal is to validate input, then I advise you not make heavy use of the PHP sanitize mechanism. Like all PHP, it is founded on the fundamentally broken philosophy of sanitizing input rather than validating it. I'm not sure what else to advise you to use, however. Respect/Validation looks promising, although I think you would be better off leaving PHP if you can.

Making do with what we have, use the following function with only FILTER_VALIDATE_* filters. You will still need to do pre- and post-processing, and you have to emulate "chained" filters with multiple calls.

function filter_array($data, $filter) {
    $missing = array_diff_key($filter, $data);
    $filtered = filter_var_array($data, $filter);
    $invalid = array_filter($filtered, function($v){return $v===FALSE;});
    $filtered = array_diff_key($filtered, $missing, $invalid);
    return array($filtered, array_keys($invalid), array_keys($missing));
}

Example in use:

$_POST = array('extra'=>'extra', 'age'=>array('30a'), 'name'=>'the name');

$expected = array(
    'name'   => array("filter" => FILTER_UNSAFE_RAW, // using this as a "passthrough" filter
                      "flags"  => FILTER_REQUIRE_SCALAR, // just to set this flag
    ),
    'age'   => array("filter"  => FILTER_VALIDATE_INT,
                     "flags"   => FILTER_REQUIRE_SCALAR,
                     "options" => array('min_range'=>0, 'max_range'=>120)
    ),
    'email' => array("filter"  => FILTER_VALIDATE_EMAIL,
                     "flags"   => FILTER_REQUIRE_SCALAR,
    ),
);

list($valid, $invalid, $missing) = filter_array($_POST, $expected);

var_export($valid); var_export($invalid); var_export($missing);
Sign up to request clarification or add additional context in comments.

7 Comments

I understand but not working either, I've updated my code for something more readable, thank you.
You are still confused about keys and values. I have updated my answer with the complete corrected code, although I would not do this the way you have done it. If you want to wait a while, I'll update the answer with how I would do this.
Ok, I understand that it might not be the best way to do it. And I'm confused about foreach $key and $value... :D
Now I understand what I was doing wrong! You're so right... the value of the array index is always assign to the first variable in the foreach condition unless $array AS $key => $value then i get a proper index. Not like $array AS $key in this example $key will allways store the index $value
Thank you very much for your great example. Can you give me a good reason to leave PHP?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.