42

这对我来说不是什么大问题(据我所知),它更多的是让我感兴趣的东西。但是,如果有的话,使用is_numericover 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
    }
?>

我假设两者的作用完全相同,但是是否有任何特定的差异可能会在以后以某种方式导致问题?是否有“最佳方式”或我没有看到的东西使它们与众不同。

4

12 回答 12

68

is_numeric()测试一个值是否是一个数字。它不一定必须是整数 - 它可以是十进制数或科学计数法中的数字。

preg_match()您给出的示例仅检查值是否包含数字 0 到 9;任意数量,任意顺序。

请注意,您给出的正则表达式也不是一个完美的整数检查器,就​​像您编写它的方式一样。它不允许负面因素;它确实允许长度为零的字符串(即根本没有数字,这可能不应该是有效的?),并且它允许数字具有任意数量的前导零,这又可能不是预期的。

[编辑]

根据您的评论,更好的正则表达式可能如下所示:

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

这会强制第一个数字仅介于 1 和 9 之间,因此您不能有前导零。它还强制它至少有一位数长,因此解决了零长度字符串问题。

你不担心负面因素,所以这不是问题。

您可能想要限制位数,因为就目前情况而言,它将允许太大而无法存储为整数的字符串。为了限制这一点,您可以将星号更改为长度限制,如下所示:

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

这将允许字符串长度在 1 到 16 位之间(即第一个数字加上 0-15 个其他数字)。随意调整花括号中的数字以满足您自己的需要。如果你想要一个固定长度的字符串,那么你只需要在大括号中指定一个数字。

希望有帮助。

于 2011-10-04T14:54:40.310 回答
12

根据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';
  }
?>
于 2011-10-04T14:57:50.323 回答
7

is_numeric() 允许任何形式的数字。所以1, 3.14159265,2.71828e10都是“数字”,而你的正则表达式归结为相当于is_int()

于 2011-10-04T14:51:56.840 回答
5

is_numeric 将接受“-0.5e+12”作为有效 ID。

于 2011-10-04T14:51:07.950 回答
5

不完全一样。

来自 is_numeric 的 PHP 文档:

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

使用您的正则表达式,您只检查“基本”数值。

is_numeric()应该更快。

于 2011-10-04T14:51:33.760 回答
5

is_numeric 检查它是否是任何类型的数字,而您的正则表达式检查它是否是整数,可能带有前导 0。对于存储为整数的 id,我们很可能不希望有前导 0。按照 Spudley 的回答,我们可以这样做:

/^[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';
}
于 2013-10-30T05:21:56.077 回答
3

is_numeric检查更多:

查找给定变量是否为数字。数字字符串由可选的符号、任意位数、可选的小数部分和可选的指数部分组成。因此 +0123.45e6 是一个有效的数值。也允许使用十六进制表示法 (0xFF),但只能没有符号、十进制和指数部分。

于 2011-10-04T14:52:00.663 回答
2

您可以使用此代码进行号码验证:

if (!preg_match("/^[0-9]+$/i", $phone)) {
        $errorMSG = 'Invalid Number!';
        $error    = 1;
    }
于 2017-11-14T12:42:03.237 回答
1

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

于 2014-06-09T14:51:21.530 回答
1

如果您检查它是否是一个数字,is_numeric()那么这里要好得多。它比正则表达式更具可读性和速度。

你的正则表达式的问题是它不允许十进制值,所以基本上你只是用is_int()正则表达式编写的。仅当您的输入中存在非标准数据格式时才应使用正则表达式;PHP 有很多内置的验证功能,甚至是没有 regex 的电子邮件验证器

于 2011-10-04T14:51:05.227 回答
0

Meanwhile, all the values above will only restrict the values to integer, so i use

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

to allow float values too.

于 2015-03-24T08:47:44.470 回答
0

您可以使用 filter_var() 检查字符串中的整数

<?php
$intnum = "1000022";
if (filter_var($intnum, FILTER_VALIDATE_INT) !== false){
    echo $intnum.' is an int now';
}else{
    echo "$intnum is not an int.";
}
// will output 1000022 is an int now
于 2021-12-16T18:12:16.713 回答