[php] 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 () 함수가 제대로 작동하지 않는 것 같습니다. URL (noobs.php? p = 1)에 “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 방식) :

# Check if your variable is an integer
if ( filter_var($variable, FILTER_VALIDATE_INT) === false ) {
  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

두 번째 옵션 (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

세 번째 옵션 (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()


답변

킥을 위해 언급 된 방법 중 몇 가지를 테스트하고 입력이 양수 또는 문자열과 동등한 것을 알 때 수년 동안 솔루션으로 사용했습니다.

나는 이것을 125,000 번의 반복으로 테스트했고, 각 반복은 동일한 변수 유형과 값 세트를 전달했습니다.

방법 1 : 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)

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

(정규식을 테스트하지도 않았어요. 진지하게 … 정규식 이요?)

참고 사항 :
방법 4는 음수 (음의 정수 또는 해당하는 문자열)에 대해 항상 false를 반환하므로 값이 양의 정수임을 일관되게 감지하는 좋은 방법입니다.
방법 1은 음의 정수에 대해 true를 반환하지만 음의 정수에 해당하는 문자열에 대해서는 false를 반환하므로 입력에 문자열 또는 정수 형식의 음수가 절대 포함되지 않는다는 확신이 없으면이 방법을 사용하지 마십시오. , 프로세스가이 동작에서 벗어나지 않습니다.

결론
따라서 입력에 음수가 포함되지 않는다고 확신하는 경우 사용 is_int하고 ctype_digit정수가 있는지 확인하는 것이 거의 두 배 빠른 것 같습니다. 변수가 문자열이고 첫 번째 문자가 대시 일 때 방법 5로 대체하는 방법 1을 사용하는 것이 그 다음으로 빠른 것입니다 (특히 입력의 대부분이 실제 정수이거나 문자열의 양수인 경우). 대체로 견고한 일관성이 필요하고 데이터의 혼합이 무엇인지 알지 못하고 일관된 방식으로 부정적인 것을 처리해야하는 경우 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>";


답변

/! \ Best anwser가 올바르지 않습니다. is_numeric ()은 정수 및 “9.1”과 같은 모든 숫자 형식에 대해 true를 반환합니다.

정수의 경우에만 친숙하지 않은 preg_match ( ‘/ ^ \ d + $ /’, $ var) 또는 명시적이고 2 배 빠른 비교를 사용할 수 있습니다.

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

추신 : 나는 이것이 오래된 게시물이지만 여전히 “php is integer”를 찾는 Google에서 세 번째라는 것을 알고 있습니다.


답변

캐스팅 연산자를 사용하여 정수로 변환 할 수 있습니다.

$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[...])항상 거짓입니다.

is_numeric을 사용 하여 문자열이 숫자로만 구성되어 있는지 (즉, 숫자로 해석 될 수 있는지) 테스트 할 수 있습니다 .