Проверка, является ли переменная целой в 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() для проверки того, является ли переменная целой, является плохой идеей. Эта функция отправит TRUE для 3.14 например. Это не ожидаемое поведение

Чтобы сделать это правильно, вы можете использовать один из следующих вариантов:

Учитывая этот массив переменных:

 $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 Way):

 # 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 Way):

 # 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 ✔ 

Третий вариант (путь 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 ✔ 

Четвертый вариант (путь 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 имеют строковый тип данных, поэтому is_int всегда возвращает false.

Вы можете увидеть это, вызвав var_dump :

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

Использование is_numeric даст желаемый результат (помните, что позволяет такие значения, как: 0x24 ).

Когда браузер отправляет p в запросе, он принимается как строка, а не int. is_int() всегда возвращает false.

Вместо этого попробуйте is_numeric() или ctype_digit()

/! \ Best anwser неверен, is_numeric () возвращает true для целого числа и всех числовых форм, таких как «9.1»,

Для целых чисел вы можете использовать недружественные preg_match ('/ ^ \ d + $ /', $ var) или явное и в 2 раза быстрее сравнение:

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

PS: Я знаю, что это старый пост, но все же третий в google ищет «php is 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 

Значения $_GET – это всегда строки – вот что такое параметры GET. Поэтому is_int($_GET[...]) всегда false.

Вы можете проверить, состоит ли строка, состоящая только из цифр (т. Е. Может быть интерпретирована как число) с is_numeric .

У меня была аналогичная проблема только сейчас!

Вы можете использовать filter_input() с FILTER_VALIDATE_INT и FILTER_NULL_ON_FAILURE для фильтрации только целочисленных значений из переменной $_GET . Работает очень аккуратно! 🙂

Проверьте мой вопрос здесь: Как проверить, является ли переменная в $ _GET Array целым числом?

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

Я тестировал это с 125 000 итераций, причем каждая итерация передавалась в том же наборе переменных типов и значений.

Метод 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,1443012046814
Способ 4: 0.0979189872742
Способ 5: 0.112988948822
Способ 6: 0,0858821868896

(Я даже не тестировал регулярное выражение, я имею в виду, серьезно … regex для этого?)

Что нужно отметить:
Метод 4 всегда возвращает false для отрицательных чисел (отрицательное целое число или эквивалент строки), поэтому является хорошим методом для последовательного определения того, что значение является положительным целым числом.
Метод 1 возвращает true для отрицательного целого числа, но false для строкового эквивалента отрицательного целого числа, поэтому не используйте этот метод, если вы не уверены, что ваш вход никогда не будет содержать отрицательное число в строковой или целочисленной форме, и если это произойдет , ваш процесс не нарушит это поведение.

Выводы
Поэтому кажется, что если вы уверены, что ваш ввод не будет содержать отрицательное число, то почти в два раза быстрее использовать is_int и ctype_digit для проверки того, что у вас есть целое число. Используя метод 1 с возвратом к методу 5, когда переменная является строкой, а первый символ – тире, является следующей самой быстрой (особенно, когда большая часть ввода представляет собой действительные целые числа или положительные числа в строке). В общем, если вам нужна прочная согласованность, и вы не представляете, что представляет собой смесь данных, и вы должны обрабатывать негативы согласованным образом, filter_var($value, FILTER_VALIDATE_INT) !== FALSE выигрывает.

Код, используемый для вывода выше:

 $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) { ... } 

Попробуйте выполнить кастинг и проверить, действительно ли это номер.

Решение doctormad неверно. попробуй это:

 $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 ()

Целое число, начинающееся с 0, приведет к фатальной ошибке с PHP 7, потому что оно может интерпретировать ее как восьмеричный символ.

Недопустимые восьмеричные литералы

Раньше восьмеричные литералы, содержащие недопустимые числа, были молча усечены (0128 было принято как 012). Теперь недействительный восьмеричный литерал вызовет ошибку синтаксического анализа.

Таким образом, вы можете удалить ведущие нули из своего целого числа:

 $var = ltrim($var, 0);