'settype() vs filter_var()
Which if the folowing lines is better to use for making sure my code is more secure. Should I be using the settype function of the filter_var functions?
settype($number,'integer')
or
filter_var($number, FILTER_SANITIZE_NUMBER_INT);
Thanking You
Solution 1:[1]
As the documentation says about FILTER_SANITIZE_NUMBER_INT:
Remove all characters except digits, plus and minus sign.
So if you are expecting for instance, an ID to be used in a SQL query, I would go with a regular expression to check that I only have digits /^[0-9]+$/. Because FILTER_SANITIZE_NUMBER_INT would allow -12 which would not make sense in this context.
The main difference between filter_var and settype is that one will parse the variable as a string, and return a string, and the other will cast it to an integer.
$string = "+12";
var_dump(filter_var($string, FILTER_SANITIZE_NUMBER_INT));
settype($string, "integer");
var_dump($string);
Output:
string(3) "+12"
int(12)
So it really depends on the context.
Solution 2:[2]
The question title is not specific on this and I am not sure if the intention was not to use \FILTER_VALIDATE_INT instead of \FILTER_SANITIZE_NUMBER_INT. So I am writing my approach here down, for people which are googling such.
In my opinion, to validate and convert, \filter_var is much closer to what "is expected" - it is not benevolent and does not bottom out to 0...
<?php
$types = [
"suffix" => "10x",
"prefix nonsenes" => "a10",
"prefix too many zeroes" => "00010",
"prefix octal" => "010",
"prefix hex" => "0x10",
"valid" => "10",
"valid plus" => "+10",
"valid minus" => "-10",
];
foreach ($types as $name => $string) {
echo "$string ($name)". PHP_EOL;
try {
$asFilter = \filter_var($string, \FILTER_VALIDATE_INT);
$asSet = $string; $settypeSuccess = \settype($asSet, "integer");
echo "\tfilter_var: "; var_dump($asFilter);
echo "\tsettype ". ($$settypeSuccess ? "successful": "FAILED") .": "; var_dump($asSet);
} catch (\Throwable $t) {
echo $t->getMessage();
}
echo PHP_EOL;
}
outputs
10x (suffix)
filter_var: bool(false)
settype successful: int(10)
a10 (prefix nonsenes)
filter_var: bool(false)
settype successful: int(0)
00010 (prefix too many zeroes)
filter_var: bool(false)
settype successful: int(10)
010 (prefix octal)
filter_var: bool(false)
settype successful: int(10)
0x10 (prefix hex)
filter_var: bool(false)
settype successful: int(0)
10 (valid)
filter_var: int(10)
settype successful: int(10)
+10 (valid plus)
filter_var: int(10)
settype successful: int(10)
-10 (valid minus)
filter_var: int(-10)
settype successful: int(-10)
For \filter_var there are also flags available: \FILTER_FLAG_ALLOW_OCTAL, \FILTER_FLAG_ALLOW_HEX, \FILTER_NULL_ON_FAILURE.
NB: Documentation for \filter_var states: "Note that scalar values are converted to string internally before they are filtered." Which can lead to unexpected behavior as reported by https://3v4l.org/CZW0W
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
