На самом деле, это очень нетривиальная задача, хотя кажется, что она простая. Когда я писал свой
класс для БД mysql, мне необходимо было научиться понимать, где int, а где float. Как в их естественном типе, так и в типе строки.
Вот что вышло:
/**
* Проверяет, является ли значение целым числом.
*
* @param mixed $input
* @return boolean
*/
function isInteger($val)
{
if (!is_scalar($val) || is_bool($val)) {
return false;
}
return isFloat($val) ? false : preg_match('~^((?:\+|-)?[0-9]+)$~', $val) === 1;
}
/**
* Проверяет, является ли значение числом с плавающей точкой.
*
* @param mixed $input
* @return boolean
*/
function isFloat($val)
{
if (!is_scalar($val) || is_bool($val)) {
return false;
}
$type = gettype($val);
if ($type === "double") {
return true;
} else {
return preg_match("/^([+-]*\\d+)*\\.(\\d+)*$/", $val) === 1;
}
}
foreach ([
'11111111111111111', 11111111111111111, // > PHP_INT_MAX - presents in PHP as float
1, '10', '+1', '1.1', 1.1, .2, 2., '.2', '2.',
'-2.', '-.2', null, [], true, false, 'string'
] as $value) {
echo $value . ':' . gettype($value) . ' is Integer? - ' . (isInteger($value) ? 'yes' : 'no') . PHP_EOL;
echo $value . ':' . gettype($value) . ' is Float? - ' . (isFloat($value) ? 'yes' : 'no') . PHP_EOL;
}
11111111111111111:string is Integer? - yes
11111111111111111:string is Float? - no
11111111111111111:integer is Integer? - yes
11111111111111111:integer is Float? - no
1:integer is Integer? - yes
1:integer is Float? - no
10:string is Integer? - yes
10:string is Float? - no
+1:string is Integer? - yes
+1:string is Float? - no
1.1:string is Integer? - no
1.1:string is Float? - yes
1,1:double is Integer? - no
1,1:double is Float? - yes
0,2:double is Integer? - no
0,2:double is Float? - yes
2:double is Integer? - no
2:double is Float? - yes
.2:string is Integer? - no
.2:string is Float? - yes
2.:string is Integer? - no
2.:string is Float? - yes
-2.:string is Integer? - no
-2.:string is Float? - yes
-.2:string is Integer? - no
-.2:string is Float? - no // тут проблема
:NULL is Integer? - no
:NULL is Float? - no
Array:array is Integer? - no
Array:array is Float? - no
1:boolean is Integer? - no
1:boolean is Float? - no
:boolean is Integer? - no
:boolean is Float? - no
string:string is Integer? - no
string:string is Float? - no
И да. Считаю, что любая т.н. "санитарная обработка" - это зло (кроме банального trim). Надо делать именно проверку данных, а любая санитария меняет данные, что не есть правильно.