Как проверить, что строка является целым числом, а не двойным и т. Д.? - PullRequest
135 голосов
/ 06 января 2010

PHP имеет функцию intval(), которая преобразует строку в целое число. Однако я хочу заранее проверить, что строка является целым числом, чтобы я мог дать пользователю полезное сообщение об ошибке, если оно неверно. PHP имеет is_int(), но возвращает строку для строки типа "2".

PHP имеет функцию is_numeric(), но она вернет true, если число является двойным. Я хочу что-то, что будет возвращать false для двойного, но true для целого.

например:.

my_is_int("2") == TRUE
my_is_int("2.1") == FALSE

Ответы [ 24 ]

1 голос
/ 17 апреля 2014
public static function isNumeric($value, $negativ = false) {
    return is_int($value) || is_string($value) && (
        ctype_digit($value) || (
            $negativ && $value{0} == '-' && ctype_digit(substr($value, 1))
        )
    );

    //alternativ:
    //return $value == (int) $value;
}
0 голосов
/ 11 декабря 2017

Если вы хотите действительно знать, является ли строка допустимым представлением истинного целочисленного типа PHP ...

in_array($string, array_map('strval', range(PHP_INT_MIN, PHP_INT_MAX)), true)

Однако это невозможно запустить, так как набор слишком велик (в этом случае он не помещается в память, если вы зациклите его, это займет слишком много циклов ЦП).

Возможно, вы можете выполнить бинарный поиск со сравнением строк, однако есть лучшие способы.

Самое простое существо:

strlen($string) <= max(strlen((string)PHP_INT_MIN), strlen((string)PHP_INT_MAX)) && $string === (string)(int)$string

Есть несколько других необычных способов подойти к нему, таких как:

is_int(array_keys([$string => null])[0])

Вы также можете выполнять сравнение строк, но вам все равно нужно будет делать такие вещи, как ctype_digit, проверять, является ли длина разумной (не тратьте ЦП, прежде чем делать такие вещи, как ctype_digit) и иметь некоторую неудобную обработку для отрицательных чисел.

Обратите внимание, что filter_var не правильно утверждает, что строка является подлинным представлением целого числа PHP. Это позволит использовать ведущие + и окружающие пробелы.

Внутренне PHP использует функцию "_zend_handle_numeric_str" для строгого сравнения, но он нигде не раскрывает это напрямую, поэтому трюк использует ключи массива (который использует его для преобразования любой строки, представляющей целое число PHP, в PHP). целое число).

Если вы хотите, чтобы двоичное безопасное преобразование в и из PHP было таким подходом.

Не всем это может понадобиться, и это может быть случай обработки пользовательского ввода. filter_var не так уж плох для этого и в большинстве случаев будет достаточно безопасным для новичков в PHP.

Проверка длины, ctype_digit, а затем проверка преобразованного значения, которое находится в диапазоне, также достаточно надежны для ввода пользователем. Более сложные схемы могут потребовать обрезки или регулярного выражения.

Проблема с большим количеством ответов здесь в этом отношении заключается в том, что, хотя вопрос неопределенный, ответов быть не должно. Если вы собираетесь предложить решение, вы должны быть в состоянии объяснить, что именно оно будет и не ожидать. Без этого нельзя сказать, соответствует ли ответ на вопрос или является безопасным. Руководство по PHP не всегда помогает, потому что оно не объясняет все предостережения для каждого из соответствующих методов, которые оно предоставляет. Такие вещи, как ctype_digit и is_int очень надежны и их легко предопределить, но особенности is_numeric, filter_var и juggling (+ $ var) или приведение типов (intval / floatval) плохо документированы.

Это PHP выдумка для вас. У него огромное количество схем для интерпретации строк как целых чисел с несогласованностями. Самый строгий метод проверки целочисленной строки не предоставляется непосредственно пользователю.

0 голосов
/ 25 марта 2019

Если вы обрабатываете числовые идентификаторы из mysql и пытаетесь навязать валидацию, чтобы он был действительным ненулевым int или int, но в строковом формате (, как mysql всегда возвращает все в строковом формате ), а не NULL. Вы можете использовать следующее. Это наиболее надежный способ проверки ошибок / предупреждений / уведомлений, который позволяет только int/string-ints, который я нашел.

...
if(empty($id) || !is_scalar($id) || !ctype_digit($id)){
  throw("Invalid ID");
}
...
0 голосов
/ 06 января 2010

Можно использовать is_numeric (), а затем проверить наличие "." в строке (не особо чувствительный к культуре).

В качестве альтернативы используйте is_numeric (), затем приведите к double и посмотрите, будет ли $ var == floor ($ var) (должно возвращать true, если это целое число).

...