1

I need to validate some values received from an HTTP request (typically from $_POST and $_GET) against their related expected type.

Here is how possible parameters are defined :

$defs = [ 
'op'       => [ 'type' => 'string' ],
'out'      => [ 'type' => 'integer'],
'throttle' => [ 'type' => 'double']
];

PHP offers the filter_var() function which actually sanitize the values but don't tell if format is valid or not.

Is there another way to achieve this without having to write a regex for each possible type (string, boolean, integer, float, double, array) ?

  • If someone already achieved this, could he provide an exemple ? Thanks. –  Jan 25 '18 at 10:15

3 Answers3

1

Edit

As it is unlikely that I will find the time to develop my library further, I am supplying another library to use.
Respect/Validation (R/V) has a lot of features to use and is ready to use now; that is, it's not a work in progress as mine is.

Here is that same working example, but using R/V.

use Respect\Validation\Validator as v;

// these are from your POST, I think
$op = "test";
$out = 10.5;
$throttle = 10.5;

$defs = [ 
    "op"       => ["type" => "string"],
    "out"      => ["type" => "integer"],
    "throttle" => ["type" => "double"]
];

foreach ($defs as $name => $settings) {
    if (v::type($settings["type"])->validate($$name)) {
        echo "<p><i>$name</i> is okay</p>";
    } else {
        echo "<p><i>$name</i> is <b>not</b> okay</p>";
    }
}

Regards to the explanation, that is the same as my original answer - with the exception of accessing errors.

In R/V, you need to try/catch errors and use a different validation method - assert. See below.

foreach ($defs as $name => $settings) {
    try {
        v::type($settings["type"])->assert($$name);
        echo "<p>No problem</p>";
    } catch (Respect\Validation\Exceptions\ExceptionInterface $ex) {
        foreach ($ex->getMessages() as $error) {
            echo "<p>$error</p>";
        }
    }
}

In the above example, the errors are caught. R/V uses getMessages to return an array of all errors. I use that to iterate over them and just print them.


Original answer below

I created a WIP library: https://github.com/JustCarty/Validator

Example

If I have understood the question correctly, then you would use it like so:

$v = new Validator();

// these are from your POST, I think
$op = "test";
$out = 10.5;
$throttle = 10.5;

$defs = [ 
    "op"       => ["type" => "string"],
    "out"      => ["type" => "integer"],
    "throttle" => ["type" => "double"]
];

foreach ($defs as $name => $settings) {
    if ($v->clearErrors()->setDataType($settings["type"])->validate($$name)) {
        echo "<p><i>$name</i> is okay</p>";
    } else {
        echo "<p><i>$name</i> is <b>not</b> okay</p>";
    }
}

Output

op is okay
out is not okay
throttle is okay

How it works

It is initialised like any other class. Just create a variable and use the new keyword.
It is chainable as you can see in the example.

The foreach loop will loop through your definitions and store the name of the variable (or string) in a variable named $name and the array of settings in a variable of $settings.
The first step is to clear the previous errors. This is because we don't initialise each iteration, we keep the same instance and change its properties. The next method is setDataType. We access the type property of the settings array and then set the data type for this validation.
The next method looks odd. The double dollar sign will evaluate in the following way (I am using the first iteration as the example):

$$name;
$op; // outputs "test"

You can read more about the double dollar here.

The errors are there to be accessed in the failed if statement. For instance, you can call $v->error, $v->errno, or $v->errorList to retrieve the last error, the error number, or all the errors respectively.

Disclaimer

There are some other options available too in the library.
Note that it is WIP and so there may be some issues.

I will also create a README at some point in time...

JustCarty
  • 3,261
  • 3
  • 26
  • 46
0

Better use filter_var function.
Documentation here: http://php.net/manual/en/function.filter-var.php

JustCarty
  • 3,261
  • 3
  • 26
  • 46
Vladimir
  • 1,342
  • 5
  • 11
0

When you just want to check the type of something there are two ways in PHP. You use the gettype function (see example) or the is_TYPE functions (TYPE is a placeholder). Here you can see the full list of is_TYPE functions. http://php.net/manual/en/book.var.php

$defs = [ 
    'op'       => [ 'type' => 'string' ],
    'out'      => [ 'type' => 'integer'],
    'throttle' => [ 'type' => 'double']
];

$in = [
    'op' => 'test',
    'out' => 123,
    'throttle' => 1.234
];

foreach ($in as $k => $v) {
    var_dump(gettype($v) === $defs[$k]['type']);
}
Stephan Muggli
  • 317
  • 2
  • 8