检查一个variables是否是PHP中的一个整数
我有以下代码
$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
我将用它来查看数据库的不同“页面”(结果1-10,11-20等)。 但是,我似乎无法使is_int()函数正常工作。 把“1”放入url(noobs.php?p = 1)给了我无效的网页错误,以及类似“asdf”的东西。
目前“最佳答案”是不正确的..
使用is_numeric()
来检查一个variables是否是一个整数是一个坏主意。 例如,这个函数将发送TRUE
3.14
。 这不是预期的行为
要正确执行此操作,可以使用以下选项之一:
考虑到这个variables数组:
$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 ];
第一个选项(FILTER_VALIDATE_INT方式):
# Check if your variable is an integer if( ! filter_var($variable, FILTER_VALIDATE_INT) ){ echo "Your variable is not an integer"; }
输出:
TEST 0 : 0 (type:integer) is not 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 ✔
第二个选项(CASTING COMPARISON方式):
# Check if your variable is an integer if ( strval($variable) != strval(intval($variable)) ) { echo "Your variable is not an integer"; }
输出:
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 ✔
第三种select(CTYPE_DIGIT方式):
# Check if your variable is an integer if( ! ctype_digit(strval($variable)) ){ echo "Your variable is not an integer"; }
输出:
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 ✔
第四种select(REGEX方式):
# Check if your variable is an integer if( ! preg_match('/^\d+$/', $variable) ){ echo "Your variable is not an integer"; }
输出:
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 ✔
所有$_GET
参数都有一个string数据types,因此, is_int
将始终返回false。
你可以通过调用var_dump
来看到这个:
var_dump($_GET['p']); // string(2) "54"
使用is_numeric
将提供所需的结果(介意你,它允许的值如: 0x24
)。
当浏览器在查询string中发送p
时,它将作为string接收,而不是int。 is_int()
将因此总是返回false。
而是尝试is_numeric()
或ctype_digit()
/!\ Best anwser不正确,is_numeric()对整数AND返回true,所有数字forms如“9.1”
对于整数,只有你可以使用不友好的preg_match('/ ^ \ d + $ /',$ var)或显式和2倍的快速比较:
if ((int) $var == $var) { // $var is an integer }
PS:我知道这是一个旧的post,但仍然是第三个在谷歌寻找“PHP是整数”
你可以尝试使用一个铸造操作符将其转换为一个整数:
$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
值$_GET
总是string – 这就是GET参数的作用。 因此, is_int($_GET[...])
总是为false。
您可以testing一个string是否只包含数字(即可以被解释为一个数字)与is_numeric 。
我刚才也有类似的问题!
您可以使用filter_input()
函数与FILTER_VALIDATE_INT
和FILTER_NULL_ON_FAILURE
过滤仅$_GET
variables中的整数值。 工作相当准确! 🙂
看看我的问题在这里: 如何检查$ _GET数组中的variables是否是一个整数?
只是为了踢,我testing了几个提到的方法,加上一个我用作解决scheme多年来,当我知道我的input是一个正数或string等值。
我testing了125,000次迭代,每次迭代传入相同的一组variablestypes和值。
方法1: is_int($value) || ctype_digit($value)
is_int($value) || ctype_digit($value)
方法2: (string)(int)$value == (string)$value
方法3: strval(intval($value)) === strval($value)
方法4: ctype_digit(strval($value))
方法5: filter_var($value, FILTER_VALIDATE_INT) !== FALSE
方法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) || (is_string($value) && $value[0] === '-' && filter_var($value, FILTER_VALIDATE_INT) !== FALSE)
方法1: 0.0552167892456
方法2: 0.126773834229
方法3: 0.143012046814
方法4: 0.0979189872742
方法5: 0.112988948822
方法6: 0.0858821868896
(我甚至没有testing正则expression式,我的意思是,认真…正则expression式呢?)
注意事项:
方法4总是返回false为负数(负整数或string等效),所以是一个很好的方法来始终检测一个值是一个正整数。
方法1对于一个负整数返回true,但对于一个等于负整数的string则返回false,所以不要使用这个方法,除非你确定你的input永远不会包含一个string或整数forms的负数,并且如果它,你的过程不会从这个行为中突破。
结论
所以,如果您确定您的input不包含负数,那么使用is_int
和ctype_digit
来validation您的整数是几乎两倍。 当variables是string且第一个字符是破折号时,使用方法1回退到方法5是下一个最快(尤其是当大多数input是string中的实际整数或正数时)。 总而言之,如果你需要稳定的一致性,并且你不知道混合数据是怎么进来的,你必须以一致的方式处理底片, filter_var($value, FILTER_VALIDATE_INT) !== FALSE
wins。
用于得到上面的输出的代码:
$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>";
$page = (isset($_GET['p']) ? (int)$_GET['p'] : 1); if ($page > 0) { ... }
尝试投射并检查它是否是最初的数字。
医生的解决scheme是不正确的。 尝试这个:
$var = '1a'; if ((int) $var == $var) { var_dump("$var is an integer, really?"); }
这打印
1a是一个整数,真的吗?
使用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"); });
这打印
1a is not int 1.1 is not int 1e is not int 0x24 is not int 9.2233720368548E+18 is not int
使用is_int($var)
这里是关于is_int()的教程