@hooligan377

Фильтрация, вопрос на засыпку?

Как будет правильно и безопасно фильтровать цифры?

Так:
$id = abs(intval($_GET['id']));

или так

$id = filter_var(trim($_GET['id']), FILTER_SANITIZE_NUMBER_INT);
  • Вопрос задан
  • 77 просмотров
Пригласить эксперта
Ответы на вопрос 3
SilenceOfWinter
@SilenceOfWinter Куратор тега PHP
та еще зажигалка...
это конечно не совсем "фильтрация", но и через is_numeric еще не один хакер не прорвался)
Ответ написан
Комментировать
sergiks
@sergiks Куратор тега PHP
♬♬
Разница двух вариантов касается ввода очень длинных значений и PHP_INT_MAX

Если введут, например, '1234567890123456789012345678901234567890',
то filter_var() вернет FALSE,
в то время, как у intval() получится 9223372036854775807.
Ответ написан
Комментировать
php666
@php666
PHP-макака
На самом деле, это очень нетривиальная задача, хотя кажется, что она простая. Когда я писал свой класс для БД 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). Надо делать именно проверку данных, а любая санитария меняет данные, что не есть правильно.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
YCLIENTS Москва
от 200 000 до 350 000 ₽
Ведисофт Екатеринбург
от 25 000 ₽
ИТЦ Аусферр Магнитогорск
от 100 000 до 160 000 ₽
25 апр. 2024, в 16:12
2000 руб./за проект
25 апр. 2024, в 16:08
130000 руб./за проект