Определение числовых переменных в PHP: от целых до дробных

Раздел: Основы PHP -> Проверка типов и значений в PHP

Основные способы проверки числа в PHP

Как точно определить, является ли переменная целым числом (int)?

$val1 = 42;
$val2 = 42.0;
$val3 = '42';
var_dump(is_int($val1)); // true
var_dump(is_int($val2)); // false (float)
var_dump(is_int($val3)); // false (string)

определить тип php (определение типа переменной в php (gettype, is_*))

Функция is_int() возвращает true только для значения с типом integer. Она не выполняет преобразование типов.

Типичная ошибка: попытка проверить строку, содержащую число. is_int('42') даёт false, что может быть неожиданно. Для таких случаев требуется предварительное преобразование или другие функции.

Как проверить, что переменная является числом с плавающей точкой (float)?

$var1 = 3.14;
$var2 = 42.0;
$var3 = '3.14';
var_dump(is_float($var1)); // true
var_dump(is_float($var2)); // true (даже если число целое)
var_dump(is_float($var3)); // false

Php определить число (проверка, является ли переменная числом (int, float) в php)

is_float() аналогично is_int() проверяет исключительно тип float.

Проблема: значение 42.0 физически хранится как float, поэтому is_float возвращает true. На практике это может быть неочевидно. Также is_float не распознаёт строковые представления.

Как определить, может ли значение быть использовано как число, включая строки?

$values = [42, 3.14, '42', '3.14', '1e2', 'abc'];
foreach ($values as $v) {
    echo is_numeric($v) ? 'true ' : 'false ';
}
// Результат: true true true true true false

Php определить массив (проверка, является ли переменная массивом в php)

is_numeric() проверяет, является ли значение числом (int/float) или строкой, содержащей допустимое числовое представление (включая экспоненциальную запись, отрицательные числа, числа с плавающей точкой).

Ошибки: is_numeric(true) возвращает true, так как true неявно приводится к 1. Пустая строка '' даёт false. Научная нотация (1e2) считается числом. Для строгих проверок используется дополнительные фильтры.

Как проверить, что строка состоит только из десятичных цифр?

$str1 = '12345';
$str2 = '-123';
$str3 = '12.34';
var_dump(ctype_digit($str1)); // true
var_dump(ctype_digit($str2)); // false (знак минус)
var_dump(ctype_digit($str3)); // false (точка)

ctype_digit() предназначена только для строк. Она возвращает true, если все символы строки являются десятичными цифрами (0-9). Не допускает отрицательные числа, дробные части или пробелы.

Проблема: пустая строка возвращает false. Для проверки на пустоту нужно дополнительное условие. Также ctype_digit не различает типы int/float.

Как проверить, что значение является целым или дробным числом с возможностью задать параметры?

$intOpt = ['options' => ['min_range' => 1, 'max_range' => 100]];
$floatOpt = ['options' => ['decimal' => '.']];
$val = '50.5';
var_dump(filter_var($val, FILTER_VALIDATE_INT, $intOpt)); // false
var_dump(filter_var($val, FILTER_VALIDATE_FLOAT)); // 50.5
var_dump(filter_var($val, FILTER_VALIDATE_FLOAT, $floatOpt)); // 50.5
// Строка '12abc' даёт false для обоих

filter_var() с константами FILTER_VALIDATE_INT и FILTER_VALIDATE_FLOAT проверяет, является ли значение целым или дробным числом в заданном формате. Для целых чисел можно указать диапазон. Фильтр возвращает само число в случае успеха или false.

Фильтр для float допускает научную запись, знаки '+' и '-', десятичную точку. Не проверяет NaN или INF. Для строгой проверки дробной части требуется регулярное выражение или дополнительные условия.

Как с помощью регулярного выражения проверить формат числа?

$patternInt = '/^[+-]?\d+$/';
$patternFloat = '/^[+-]?\d+(\.\d+)?$/';
$val = '-42.7';
var_dump(preg_match($patternInt, $val)); // 0
var_dump(preg_match($patternFloat, $val)); // 1

Регулярные выражения дают полный контроль над форматом. Например, можно требовать определённое количество цифр после запятой, запретить научную запись, указать допустимый знак и т.д.

Высокая сложность написания и отладки. Не учитывают переполнение целых чисел (PHP автоматически преобразует в float). Для больших чисел проверка через is_numeric может быть проще.

Выбор метода зависит от задачи. Если требуется строгая типизация is_int/is_float. Для проверки пользовательского ввода (строки) лучше использовать filter_var или is_numeric с последующим приведением типа. Для специфических форматов подойдут регулярные выражения.

Расширенные примеры проверки чисел в PHP

Проверка с комбинацией is_numeric и приведения типа

Пример
function isStrictNumber($val) {
    if (is_numeric($val)) {
        settype($val, is_float($val + 0) ? 'float' : 'int');
        return $val;
    }
    return false;
}
$tests = ['42', '3.14', '1e2', 'abc', true, null];
foreach ($tests as $t) {
    $res = isStrictNumber($t);
    echo ($res === false ? 'false' : $res) . ' (' . gettype($res) . ')\n';
}
// Результат:
// 42 (integer)
// 3.14 (double)
// 100 (integer) - научная запись преобразуется в целое?
// false (boolean)
// 1 (integer) - true приводится к 1
// false (boolean)
42 (integer)
3.14 (double)
100 (integer)
false (boolean)
1 (integer)
false (boolean)

Как обработать пользовательский ввод из формы?

Пример
$input = $_POST['age'] ?? '';
if (filter_var($input, FILTER_VALIDATE_INT, ['options' => ['min_range' => 0, 'max_range' => 150]])) {
    $age = (int)$input;
    echo "Возраст принят: $age";
} else {
    echo "Некорректный возраст";
}

Проверка массива чисел с разными типами

Пример
$data = [1, 2.5, '3', '4.2', 'five'];
$filtered = array_filter($data, function($v) {
    return is_int($v) || is_float($v) || (is_string($v) && preg_match('/^\d+(\.\d+)?$/', $v));
});
print_r($filtered);
// Результат:
// Array ( [0] => 1 [1] => 2.5 [2] => 3 [3] => 4.2 )
Array
(
    [0] => 1
    [1] => 2.5
    [2] => 3
    [3] => 4.2
)

Проверка на бесконечность и NaN

Пример
$values = [log(0), INF, NAN, 1.0/0, 'inf', 'nan'];
foreach ($values as $v) {
    echo "$v : ";
    if (is_numeric($v)) {
        echo (is_finite($v) ? 'finite' : (is_infinite($v) ? 'infinite' : 'nan')) . "\n";
    } else {
        echo "not numeric\n";
    }
}
// Результат:
// -INF : infinite
// INF : infinite
// NAN : nan
// INF : infinite
// inf : not numeric
// nan : not numeric
-INF : infinite
INF : infinite
NAN : nan
INF : infinite
inf : not numeric
nan : not numeric

Сравнение производительности различных методов

Пример
$tests = ['42', 42, 3.14, '3.14', 'abc', '', true];
$methods = ['is_int', 'is_float', 'is_numeric', 'ctype_digit', 'filter_int', 'filter_float'];
foreach ($methods as $func) {
    $start = microtime(true);
    for ($i = 0; $i < 10000; $i++) {
        foreach ($tests as $v) {
            switch ($func) {
                case 'is_int': is_int($v); break;
                case 'is_float': is_float($v); break;
                case 'is_numeric': is_numeric($v); break;
                case 'ctype_digit': ctype_digit($v); break;
                case 'filter_int': filter_var($v, FILTER_VALIDATE_INT); break;
                case 'filter_float': filter_var($v, FILTER_VALIDATE_FLOAT); break;
            }
        }
    }
    $time = microtime(true) - $start;
    echo "$func: " . round($time, 5) . " сек\n";
}
// Результат (примерный):
// is_int: 0.00250 сек
// is_float: 0.00248 сек
// is_numeric: 0.00310 сек
// ctype_digit: 0.00290 сек
// filter_int: 0.00420 сек
// filter_float: 0.00450 сек
is_int: 0.00250 сек
is_float: 0.00248 сек
is_numeric: 0.00310 сек
ctype_digit: 0.00290 сек
filter_int: 0.00420 сек
filter_float: 0.00450 сек

Преобразование строки в число с проверкой потери данных

Пример
function safeConvert($str) {
    if (!is_string($str) && !is_int($str) && !is_float($str)) return null;
    $num = $str + 0;
    if (is_numeric($str) && (string)$num === (string)$str) {
        return $num;
    }
    return null;
}
$tests = ['42', '42.0', '3.14', '1e2', '0123', '0x1F', ' 5', '5 '];
foreach ($tests as $t) {
    $res = safeConvert($t);
    echo var_export($t, true) . ' => ' . var_export($res, true) . "\n";
}
// Результат:
// '42' => 42
// '42.0' => 42.0
// '3.14' => 3.14
// '1e2' => 100.0
// '0123' => 123
// '0x1F' => null (шестнадцатеричное не пройдёт, так как (string)$num = '31')
// ' 5' => null (пробелы)
// '5 ' => null
'42' => 42
'42.0' => 42.0
'3.14' => 3.14
'1e2' => 100.0
'0123' => 123
'0x1F' => null
' 5' => null
'5 ' => null

Эти примеры демонстрируют, как в разных ситуациях выбирать подходящую проверку и учитывать тонкости PHP.

Проверка, является ли переменная числом (int, float) в PHP - comments

En
Php определить число (php)