Проверка подлинности PHP is_numeric или preg_match 0-9 - программирование

Проверка подлинности PHP is_numeric или preg_match 0-9

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

Пример 1:

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

Пример два:

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

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

4b9b3361

Ответ 1

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

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

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

[EDIT]

В соответствии с вашим комментарием лучшее регулярное выражение может выглядеть так:

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

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

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

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

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

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

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

Ответ 2

Согласно 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';
  }
?>

Ответ 3

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

Ответ 4

is_numeric примет "-0.5e + 12" в качестве действительного идентификатора.

Ответ 5

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

Из документов 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() должен быть быстрее.

Ответ 6

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

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

Однако, как отмечает Spudley, результирующая строка может быть слишком большой, чтобы быть сохраненной как 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';
}

Ответ 7

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

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

Ответ 8

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

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

Ответ 9

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} $/

Ответ 10

Между тем все значения, указанные выше, будут только ограничивать значения целыми числами, поэтому я использую

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

чтобы также допускать значения float.

Ответ 11

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

if (!preg_match("/^[0-9]+$/i", $phone)) {
        $errorMSG = 'Invalid Number!';
        $error    = 1;
    }