检查变量是否是 PHP 中的整数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6416763/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 00:19:37  来源:igfitidea点击:

Checking if a variable is an integer in PHP

php

提问by ahota

I have the following code

我有以下代码

    $page = $_GET['p'];

    if($page == "")
    {
        $page = 1;
    }
    if(is_int($page) == false)
    {
        setcookie("error", "Invalid page.", time()+3600);
        header("location:somethingwentwrong.php");
        die();
    }
    //else continue with code

which I am going to use for looking at different "pages" of a database (results 1-10, 11-20, etc). I can't seem to get the is_int() function to work correctly, however. Putting "1" into the url (noobs.php?p=1) gives me the invalid page error, as well as something like "asdf".

我将用它来查看数据库的不同“页面”(结果 1-10、11-20 等)。但是,我似乎无法让 is_int() 函数正常工作。将“1”放入 url (noobs.php?p=1) 会给我无效页面错误,以及类似“asdf”的错误。

回答by CaM2091

Using is_numeric()for checking if a variable is an integer is a bad idea. This function will return TRUEfor 3.14for example. It's not the expected behavior.

使用is_numeric()检查,如果一个变量是一个整数是一个坏主意。该函数将返回TRUE用于3.14例如。这不是预期的行为。

To do this correctly, you can use one of these options:

要正确执行此操作,您可以使用以下选项之一:

Considering this variables array :

考虑到这个变量数组:

$variables = [
    "TEST 0" => 0,
    "TEST 1" => 42,
    "TEST 2" => 4.2,
    "TEST 3" => .42,
    "TEST 4" => 42.,
    "TEST 5" => "42",
    "TEST 6" => "a42",
    "TEST 7" => "42a",
    "TEST 8" => 0x24,
    "TEST 9" => 1337e0
];

The first option (FILTER_VALIDATE_INT way) :

第一个选项(FILTER_VALIDATE_INT 方式):

# Check if your variable is an integer
if ( filter_var($variable, FILTER_VALIDATE_INT) === false ) {
  echo "Your variable is not an integer";
}

Output :

输出 :

TEST 0 : 0 (type:integer) is an integer ?
TEST 1 : 42 (type:integer) is an integer ?
TEST 2 : 4.2 (type:double) is not an integer ?
TEST 3 : 0.42 (type:double) is not an integer ?
TEST 4 : 42 (type:double) is an integer ?
TEST 5 : 42 (type:string) is an integer ?
TEST 6 : a42 (type:string) is not an integer ?
TEST 7 : 42a (type:string) is not an integer ?
TEST 8 : 36 (type:integer) is an integer ?
TEST 9 : 1337 (type:double) is an integer ?

The second option (CASTING COMPARISON way) :

第二个选项(铸造比较方式):

# Check if your variable is an integer
if ( strval($variable) !== strval(intval($variable)) ) {
  echo "Your variable is not an integer";
}

Output :

输出 :

TEST 0 : 0 (type:integer) is an integer ?
TEST 1 : 42 (type:integer) is an integer ?
TEST 2 : 4.2 (type:double) is not an integer ?
TEST 3 : 0.42 (type:double) is not an integer ?
TEST 4 : 42 (type:double) is an integer ?
TEST 5 : 42 (type:string) is an integer ?
TEST 6 : a42 (type:string) is not an integer ?
TEST 7 : 42a (type:string) is not an integer ?
TEST 8 : 36 (type:integer) is an integer ?
TEST 9 : 1337 (type:double) is an integer ?

The third option (CTYPE_DIGIT way) :

第三个选项(CTYPE_DIGIT方式):

# Check if your variable is an integer
if ( ! ctype_digit(strval($variable)) ) {
  echo "Your variable is not an integer";
}

Output :

输出 :

TEST 0 : 0 (type:integer) is an integer ?
TEST 1 : 42 (type:integer) is an integer ?
TEST 2 : 4.2 (type:double) is not an integer ?
TEST 3 : 0.42 (type:double) is not an integer ?
TEST 4 : 42 (type:double) is an integer ?
TEST 5 : 42 (type:string) is an integer ?
TEST 6 : a42 (type:string) is not an integer ?
TEST 7 : 42a (type:string) is not an integer ?
TEST 8 : 36 (type:integer) is an integer ?
TEST 9 : 1337 (type:double) is an integer ?

The fourth option (REGEX way) :

第四个选项(REGEX方式):

# Check if your variable is an integer
if ( ! preg_match('/^\d+$/', $variable) ) {
  echo "Your variable is not an integer";
}

Output :

输出 :

TEST 0 : 0 (type:integer) is an integer ?
TEST 1 : 42 (type:integer) is an integer ?
TEST 2 : 4.2 (type:double) is not an integer ?
TEST 3 : 0.42 (type:double) is not an integer ?
TEST 4 : 42 (type:double) is an integer ?
TEST 5 : 42 (type:string) is an integer ?
TEST 6 : a42 (type:string) is not an integer ?
TEST 7 : 42a (type:string) is not an integer ?
TEST 8 : 36 (type:integer) is an integer ?
TEST 9 : 1337 (type:double) is an integer ?

回答by Tim Cooper

All $_GETparameters have a string datatype, therefore, is_intwill always return false.

所有$_GET参数都有一个字符串数据类型,因此,is_int将始终返回 false。

You can see this by calling var_dump:

您可以通过调用来查看var_dump

var_dump($_GET['p']); // string(2) "54"

Using is_numericwill provide the desired result (mind you, that allows values such as: 0x24).

使用is_numeric将提供所需的结果(请注意,允许使用诸如: 之类的值0x24)。

回答by Michael Berkowski

When the browser sends pin the querystring, it is received as a string, not an int. is_int()will therefore always return false.

当浏览器发送p查询字符串时,它是作为字符串接收的,而不是整数。 is_int()因此将始终返回 false。

Instead try is_numeric()or ctype_digit()

而是尝试is_numeric()ctype_digit()

回答by Jonathan Falkner

Just for kicks, I tested out a few of the mentioned methods, plus one I've used as my go to solution for years when I know my input is a positive number or string equivalent.

只是为了好玩,我测试了一些提到的方法,加上一个我多年来一直用作我的解决方案的方法,当我知道我的输入是一个正数或字符串时。

I tested this with 125,000 iterations, with each iteration passing in the same set of variable types and values.

我用 125,000 次迭代对此进行了测试,每次迭代都传入相同的一组变量类型和值。

Method 1:is_int($value) || ctype_digit($value)
Method 2:(string)(int)$value == (string)$value
Method 3:strval(intval($value)) === strval($value)
Method 4:ctype_digit(strval($value))
Method 5:filter_var($value, FILTER_VALIDATE_INT) !== FALSE
Method 6:is_int($value) || ctype_digit($value) || (is_string($value) && $value[0] === '-' && filter_var($value, FILTER_VALIDATE_INT) !== FALSE)

方法一:is_int($value) || ctype_digit($value)
方法二:(string)(int)$value == (string)$value
方法三:strval(intval($value)) === strval($value)
方法四:ctype_digit(strval($value))
方法五:filter_var($value, FILTER_VALIDATE_INT) !== FALSE
方法六:is_int($value) || ctype_digit($value) || (is_string($value) && $value[0] === '-' && filter_var($value, FILTER_VALIDATE_INT) !== FALSE)

Method 1:0.0552167892456
Method 2:0.126773834229
Method 3:0.143012046814
Method 4:0.0979189872742
Method 5:0.112988948822
Method 6:0.0858821868896

方法1:0.0552167892456
方法2:0.126773834229
方法3:0.143012046814
方法4:0.0979189872742
方法5:0.112988948822
方法6:0.0858821868896

(I didn't even test the regex, I mean, seriously... regex for this?)

(我什至没有测试正则表达式,我的意思是,认真......正则表达式?)

Things to note:
Method 4 always returns false for negative numbers (negative integer or string equivalent), so is a good method to consistently detect that a value is a positive integer.
Method 1 returns true for a negative integer, but false for a string equivalent of a negative integer, so don't use this method unless you are certain your input will never contain a negative number in string or integer form, and that if it does, your process won't break from this behavior.

注意事项:
对于负数(负整数或等效字符串),方法 4 始终返回 false,因此是一致检测值是否为正整数的好方法。
方法 1 对负整数返回 true,但对与负整数等效的字符串返回 false,所以不要使用此方法,除非您确定您的输入永远不会包含字符串或整数形式的负数,并且如果确实如此,您的流程不会中断此行为。

Conclusions
So it seems that if you are certain that your input will not include a negative number, then it is almost twice as fast to use is_intand ctype_digitto validate that you have an integer. Using Method 1 with a fallback to method 5 when the variable is a string and the first character is a dash is the next fastest (especially when a majority of the input is actual integers or positive numbers in a string). All in all, if you need solid consistency, and you have no idea what the mix of data is coming in, and you must handle negatives in a consistent fashion, filter_var($value, FILTER_VALIDATE_INT) !== FALSEwins.

结论
因此,如果您确定您的输入不包含负数,那么使用is_intctype_digit验证您是否有整数的速度几乎是其两倍。当变量是字符串且第一个字符是破折号时,使用方法 1 并回退到方法 5 是次快的(尤其是当大多数输入是字符串中的实际整数或正数时)。总而言之,如果您需要可靠的一致性,并且您不知道传入的数据组合是什么,并且您必须以一致的方式处理负面信息,那么您就filter_var($value, FILTER_VALIDATE_INT) !== FALSE赢了。

Code used to get the output above:

用于获取上述输出的代码:

$u = "-10";
$v = "0";
$w = 0;
$x = "5";
$y = "5c";
$z = 1.44;

function is_int1($value){
    return (is_int($value) || ctype_digit($value));
}

function is_int2($value) {
    return ((string)(int)$value == (string)$value);
}

function is_int3($value) {
    return (strval(intval($value)) === strval($value));
}

function is_int4($value) {
    return (ctype_digit(strval($value)));
}

function is_int5($value) {
    return filter_var($value, FILTER_VALIDATE_INT) !== FALSE;
}

function is_int6($value){
    return (is_int($value) || ctype_digit($value) || (is_string($value) && $value[0] === '-' && filter_var($value, FILTER_VALIDATE_INT)) !== FALSE);
}

$start = microtime(TRUE);
for ($i=0; $i < 125000; $i++) {
  is_int1($u);
  is_int1($v);
  is_int1($w);
  is_int1($x);
  is_int1($y);
  is_int1($z);
}
$stop = microtime(TRUE);
$start2 = microtime(TRUE);
for ($j=0; $j < 125000; $j++) {
  is_int2($u);
  is_int2($v);
  is_int2($w);
  is_int2($x);
  is_int2($y);
  is_int2($z);
}
$stop2 = microtime(TRUE);
$start3 = microtime(TRUE);
for ($k=0; $k < 125000; $k++) {
  is_int3($u);
  is_int3($v);
  is_int3($w);
  is_int3($x);
  is_int3($y);
  is_int3($z);
}
$stop3 = microtime(TRUE);
$start4 = microtime(TRUE);
for ($l=0; $l < 125000; $l++) {
  is_int4($u);
  is_int4($v);
  is_int4($w);
  is_int4($x);
  is_int4($y);
  is_int4($z);
}
$stop4 = microtime(TRUE); 

$start5 = microtime(TRUE);
for ($m=0; $m < 125000; $m++) {
  is_int5($u);
  is_int5($v);
  is_int5($w);
  is_int5($x);
  is_int5($y);
  is_int5($z);
}
$stop5 = microtime(TRUE); 

$start6 = microtime(TRUE);
for ($n=0; $n < 125000; $n++) {
  is_int6($u);
  is_int6($v);
  is_int6($w);
  is_int6($x);
  is_int6($y);
  is_int6($z);
}
$stop6 = microtime(TRUE); 

$time = $stop - $start;  
$time2 = $stop2 - $start2;  
$time3 = $stop3 - $start3;  
$time4 = $stop4 - $start4;  
$time5 = $stop5 - $start5;  
$time6 = $stop6 - $start6;  
print "**Method 1:** $time <br>";
print "**Method 2:** $time2 <br>";
print "**Method 3:** $time3 <br>";
print "**Method 4:** $time4 <br>";  
print "**Method 5:** $time5 <br>";  
print "**Method 6:** $time6 <br>";  

回答by job3dot5

/!\ Best anwser is not correct, is_numeric() returns true for integer AND all numeric forms like "9.1"

/!\ 最佳答案不正确,is_numeric() 对整数和所有数字形式(如“9.1”)返回 true

For integer only you can use the unfriendly preg_match('/^\d+$/', $var) or the explicit and 2 times faster comparison :

对于整数,您可以使用不友好的 preg_match('/^\d+$/', $var) 或显式和 2 倍快的比较:

if ((int) $var == $var) {
    // $var is an integer
}

PS: i know this is an old post but still the third in google looking for "php is integer"

PS:我知道这是一个旧帖子,但仍然是谷歌中寻找“php is integer”的第三个帖子

回答by Drewdin

You could try using a casting operator to convert it to an integer:

您可以尝试使用强制转换运算符将其转换为整数:

$page = (int) $_GET['p'];

if($page == "")
{
    $page = 1;
}
if(empty($page) || !$page)
{
    setcookie("error", "Invalid page.", time()+3600);
    header("location:somethingwentwrong.php");
    die();
}
//else continue with code

回答by maxxon15

I had a similar problem just now!

我刚才也遇到了类似的问题!

You can use the filter_input()function with FILTER_VALIDATE_INTand FILTER_NULL_ON_FAILUREto filter only integer values out of the $_GETvariable. Works pretty accurately! :)

您可以将该filter_input()函数与FILTER_VALIDATE_INTFILTER_NULL_ON_FAILURE一起使用,以仅从$_GET变量中过滤出整数值。工作非常准确!:)

Check out my question here: How to check whether a variable in $_GET Array is an integer?

在这里查看我的问题:如何检查 $_GET 数组中的变量是否为整数?

回答by Aleksandr

doctormad's solution is not correct. try this:

Doctormad 的解决方案是不正确的。尝试这个:

$var = '1a';
if ((int) $var == $var) {
    var_dump("$var is an integer, really?");
}

this prints

这打印

1a is an integer, really?"

1a 是一个整数,真的吗?”

use filter_var()with FILTER_VALIDATE_INTargument

使用filter_var()FILTER_VALIDATE_INT参数

$data = Array('0', '1', '1a', '1.1', '1e', '0x24', PHP_INT_MAX+1);
array_walk($data, function ($num){
$is_int = filter_var($num, FILTER_VALIDATE_INT);
if ($is_int === false)
var_dump("$num is not int");
});

this prints

这打印

1a is not int 
1.1 is not int
1e is not int
0x24 is not int
9.2233720368548E+18 is not int

回答by phihag

Values $_GETare always strings – that's what GET paramters come as. Therefore, is_int($_GET[...])is always false.

$_GET总是字符串——这就是 GET 参数的来源。所以,is_int($_GET[...])永远是假的。

You can test if a string consists only of digits(i.e. could be interpreted as a number) with is_numeric.

您可以使用is_numeric测试字符串是否仅由数字组成(即可以解释为数字)。

回答by Brad Christie

$page = (isset($_GET['p']) ? (int)$_GET['p'] : 1);
if ($page > 0)
{
  ...
}

Try casting and checking if it's a number initially.

尝试投射并检查它最初是否为数字。