PHP is_numeric или preg_match 0-9 проверки - PullRequest
35 голосов
/ 04 октября 2011

Это не большая проблема для меня (насколько я знаю), это больше меня интересует.Но в чем главное отличие использования is_numeric над preg_match (или наоборот) для проверки введенных пользователем значений.

Пример первый:

<?php
    $id = $_GET['id'];
    if (!preg_match('/^[0-9]*$/', $id)) {
        // Error
    } else {
        // Continue
    }
?>

Пример два:

<?php
    $id = $_GET['id'];
    if (!is_numeric($id)) {
        // Error
    } else {
        // Continue
    }
?>

Я предполагаю, что оба делают одно и то же, но есть ли какие-то конкретные различия, которые могут как-то вызвать проблемы позже?Есть ли "лучший способ" или что-то, чего я не вижу, что отличает их от других.

Ответы [ 11 ]

61 голосов
/ 04 октября 2011

is_numeric() проверяет, является ли значение числом.Это не обязательно должно быть целое число - это может быть десятичное число или число в научной нотации.

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

Обратите внимание, что заданное вами регулярное выражение также не является идеальным средством проверки целых чисел, как вы его написали.Это не учитывает негативов;он допускает строку нулевой длины (т. е. без цифр вообще, что, по-видимому, не должно быть действительным?), и позволяет номеру иметь любое число ведущих нулей, что опять-таки может не быть предназначенным.

[EDIT]

Согласно вашему комментарию, более правильное регулярное выражение может выглядеть следующим образом:

/^[1-9][0-9]*$/

Это заставляет первую цифру быть только между 1 и 9, поэтомуВы не можете иметь ведущие нули.Это также заставляет его иметь длину не менее одной цифры, поэтому решает проблему с нулевой длиной строки.

Вы не беспокоитесь о негативах, так что это не проблема.

Возможно, вы захотитеограничить количество цифр, потому что при существующем состоянии это позволит слишком большим строкам храниться в виде целых чисел.Чтобы ограничить это, вы должны изменить звезду на ограничение длины следующим образом:

/^[1-9][0-9]{0,15}$/

Это позволит длине строки от 1 до 16 цифр (т.е. первая цифра плюс 0-15 дополнительных цифр),Не стесняйтесь корректировать числа в фигурных скобках в соответствии с вашими потребностями.Если вам нужна строка фиксированной длины, вам нужно указать только одно число в фигурных скобках.

Надеюсь, это поможет.

11 голосов
/ 04 октября 2011

Согласно http://www.php.net/manual/en/function.is-numeric.php, is_numeric допускает что-то вроде "+ 0123.45e6" или "0xFF". Я думаю, что это не то, что вы ожидаете.

preg_match может быть медленным, и вы можете иметь что-то вроде 0000 или 0051.

Я предпочитаю использовать ctype_digit (работает только со строками, это нормально с $ _GET).

<?php
  $id = $_GET['id'];
  if (ctype_digit($id)) {
      echo 'ok';
  } else {
      echo 'nok';
  }
?>
7 голосов
/ 04 октября 2011

is_numeric () разрешает любую форму числа.так что 1, 3.14159265, 2.71828e10 все "числовые", в то время как ваше регулярное выражение сводится к эквиваленту is_int()

5 голосов
/ 30 октября 2013

is_numeric проверяет, является ли это какое-либо число, в то время как ваше регулярное выражение проверяет, является ли оно целым числом, возможно, с ведущими 0. Для идентификатора, хранящегося в виде целого числа, вполне вероятно, что у нас не будет ведущих нулей. Следуя ответу Спадли, мы можем сделать:

/^[1-9][0-9]*$/

Однако, как отмечает Спудли, результирующая строка может быть слишком большой, чтобы ее можно было сохранить как 32-разрядное или 64-разрядное целочисленное значение. Максимальное значение 32-разрядного целого числа со знаком составляет 2 147 483 647 (10 цифр), а максимальное 64-разрядного целого числа со знаком составляет 9 223 372 036 854 775 807 (19 цифр). Однако многие 10- и 19-значные целые числа больше, чем максимальные 32-разрядные и 64-разрядные целые числа соответственно. Простое решение только для регулярных выражений будет:

/^[1-9][0-9]{0-8}$/ 

или

/^[1-9][0-9]{0-17}$/

соответственно, но эти «решения», к сожалению, ограничивают каждое из 9 и 19-значных чисел; вряд ли удовлетворительный результат. Лучшим решением может быть что-то вроде:

$expr = '/^[1-9][0-9]*$/';
if (preg_match($expr, $id) && filter_var($id, FILTER_VALIDATE_INT)) {
    echo 'ok';
} else {
    echo 'nok';
}
5 голосов
/ 04 октября 2011

Не совсем то же самое.

Из документов PHP is_numeric:

'42' is numeric
'1337' is numeric
'1e4' is numeric
'not numeric' is NOT numeric
'Array' is NOT numeric
'9.1' is numeric

С помощью регулярного выражения вы проверяете только «базовые» числовые значения.

Также is_numeric() должно быть быстрее.

5 голосов
/ 04 октября 2011

is_numeric будет принимать «-0,5e + 12» в качестве действительного идентификатора.

3 голосов
/ 04 октября 2011

is_numeric проверяет больше:

Находит, является ли данная переменная числовой.Числовые строки состоят из необязательного знака, любого количества цифр, необязательной десятичной части и необязательной экспоненциальной части.Таким образом, + 0123.45e6 является допустимым числовым значением.Шестнадцатеричное обозначение (0xFF) также допускается, но только без знака, десятичной и экспоненциальной частей.

1 голос
/ 14 ноября 2017

Вы можете использовать этот код для проверки номера:

if (!preg_match("/^[0-9]+$/i", $phone)) {
        $errorMSG = 'Invalid Number!';
        $error    = 1;
    }
1 голос
/ 09 июня 2014

PHP * is_numeric функция учитывает как числа с плавающей точкой, так и целые числа.В то же время, функция is_int является слишком строгой, если вы хотите проверять данные формы (только строки).Следовательно, для этого обычно лучше всего использовать регулярные выражения.

Строго говоря, целые числа - это целые числа, положительные и отрицательные, а также ноль.Вот регулярное выражение для этого:

/ ^ 0 $ | ^ [-]? [1-9] [0-9] * $ /

ИЛИ, если вы хотите разрешить ведущие нули:

/ ^ [-]? [0] | [1-9] [0-9] $ /

Обратите внимание, что это позволит использовать такие значения, как -0000, что, однако, не вызывает проблем в PHP.(MySQL также приведёт к таким значениям, как 0.)

Вы также можете ограничить длину целого числа из соображений 32/64-битных возможностей платформы PHP и / или совместимости базы данных,Например, чтобы ограничить длину целого числа 9 цифрами (исключая необязательный знак -), вы можете использовать:

/ ^ 0 $ | ^ [-]? [1-9] [0-9] {0,8} $ /

1 голос
/ 04 октября 2011

Если вы только проверяете, является ли это число, is_numeric() намного намного лучше здесь. Это более читабельно и немного быстрее, чем регулярное выражение.

Проблема с вашим регулярным выражением в том, что он не допускает десятичные значения, поэтому по сути вы только что написали is_int() в регулярном выражении. Регулярные выражения следует использовать только в том случае, если во входных данных присутствует нестандартный формат данных; PHP имеет множество встроенных функций проверки, даже средство проверки электронной почты без регулярных выражений .

...