检查变量是否是 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
Checking if a variable is an integer in 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 TRUE
for 3.14
for 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 $_GET
parameters have a string datatype, therefore, is_int
will 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_numeric
will provide the desired result (mind you, that allows values such as: 0x24
).
使用is_numeric
将提供所需的结果(请注意,允许使用诸如: 之类的值0x24
)。
回答by Michael Berkowski
When the browser sends p
in 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_int
and ctype_digit
to 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) !== FALSE
wins.
结论
因此,如果您确定您的输入不包含负数,那么使用is_int
和ctype_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_INT
and FILTER_NULL_ON_FAILURE
to filter only integer values out of the $_GET
variable. Works pretty accurately! :)
您可以将该filter_input()
函数与FILTER_VALIDATE_INT
和FILTER_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 $_GET
are 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.
尝试投射并检查它最初是否为数字。