Jak sprawdzić, czy string jest int, ale nie double, itd.?

155

PHP ma intval()funkcję, która konwertuje ciąg znaków na liczbę całkowitą. Jednak chcę wcześniej sprawdzić, czy łańcuch jest liczbą całkowitą, aby móc przekazać użytkownikowi pomocny komunikat o błędzie, jeśli jest nieprawidłowy. PHP ma is_int(), ale zwraca false dla łańcucha znaków, takiego jak "2".

PHP ma tę is_numeric()funkcję, ale zwróci ona wartość true, jeśli liczba jest podwójna. Chcę czegoś, co zwróci fałsz dla podwójnej, ale prawdziwe dla int.

na przykład:

my_is_int("2") == TRUE
my_is_int("2.1") == FALSE
Rory
źródło
6
jak należy traktować „2.0”?
nickf

Odpowiedzi:

183

A co powiesz na używanie ctype_digit?

Z instrukcji:

<?php
$strings = array('1820.20', '10002', 'wsl!12');
foreach ($strings as $testcase) {
    if (ctype_digit($testcase)) {
        echo "The string $testcase consists of all digits.\n";
    } else {
        echo "The string $testcase does not consist of all digits.\n";
    }
}
?>

Powyższy przykład wyświetli:

Ciąg 1820.20 nie składa się ze wszystkich cyfr.
Ciąg 10002 składa się ze wszystkich cyfr.
Ciąg wsl! 12 nie składa się z wszystkich cyfr.

Działa to tylko wtedy, gdy dane wejściowe są zawsze ciągiem znaków:

$numeric_string = '42';
$integer        = 42;

ctype_digit($numeric_string);  // true
ctype_digit($integer);         // false

Jeśli dane wejściowe mogą być typu int, połącz je ctype_digitz is_int.

Jeśli dbasz o liczbach ujemnych, następnie trzeba sprawdzić wejście do poprzedzającego -, a jeśli tak, to wezwanie ctype_digitna zasadzie substrłańcucha wejściowego. Coś takiego mogłoby to zrobić:

function my_is_int($input) {
  if ($input[0] == '-') {
    return ctype_digit(substr($input, 1));
  }
  return ctype_digit($input);
}
Dominic Rodger
źródło
7
liczby ujemne?
Anurag
1
@Anurag, edytowane w języku (chociaż jeśli naprawdę zależy ci na tym, regex jest prawdopodobnie prostszy).
Dominic Rodger,
4
Jeśli chcesz sprawdzić ujemne liczby całkowite, dodaj użycie abs () w ten sposób ctype_digit(abs($str))zamiast po prostu ctype_digit.
enchance
3
@enchance abs('definitelynotanint') === 0. co więcej, ctype_digittrwa tylko smyczki
Klesun
To nie jest poprawne. Duża liczba całkowita w PHP to podwójna!
jgmjgm
91

filter_var powinien to zrobić:

var_dump(filter_var('2', FILTER_VALIDATE_INT));   // 2
var_dump(filter_var('2.0', FILTER_VALIDATE_INT)); // false
var_dump(filter_var('2.1', FILTER_VALIDATE_INT)); // false

ale

var_dump(filter_var(2, FILTER_VALIDATE_INT));     // 2
var_dump(filter_var(2.0, FILTER_VALIDATE_INT));   // 2
var_dump(filter_var(2.1, FILTER_VALIDATE_INT));   // false

Jeśli chcesz, aby wartości logiczne były tylko zwracane, opakuj je w funkcję, np

function validatesAsInt($number)
{
    $number = filter_var($number, FILTER_VALIDATE_INT);
    return ($number !== FALSE);
}
Gordon
źródło
2
Podoba mi się większość odpowiedzi, ale myślę, że ta jest najbardziej elegancka.
Ian Dunn
6
@grenoult 3v4l.org/qVRRS daje int 0 dla łańcuchów i liczb całkowitych, więc nie wiesz, dlaczego uważasz, że to nie działa. Czy porównujesz wynik z ==być może?
Gordon
1
@Gordon mój błąd, rzeczywiście porównywałem tylko z if 3v4l.org/IAvCF
Guillaume Renoult
Spowoduje to wykonanie dziwnych rzeczy, na przykład zwrócenie prawdy dla „+123”. Jest łagodzony przez to, że ma zwrócić prawdziwy int, ale nadal może nie być tym, czego chcą ludzie, czyli ścisłym sprawdzaniem int.
jgmjgm
@ MohammedRédaOUASSINI OP poprosił o sprawdzenie ciągów , a nie pływaków. To będzie działać, jeśli przejdzie w „-1.0” (ciąg) Będzie nie praca, jeśli przechodzą w -1,0 (float), ale to nie był wymóg, aby rozpocząć. Zobacz 3v4l.org/bOX6X
Gordon
20

+1 do odpowiedzi Dominica (używanie ctype_digit). Innym sposobem, w jaki możesz to zrobić, jest wymuszenie typu:

$inty = "2";
$inty2 = " 2";
$floaty = "2.1";
$floaty2 = "2.0";

is_int($inty + 0); // true
is_int($floaty + 0); // false
is_int($floaty2 + 0); // false

// here's difference between this and the ctype functions.
is_int($inty2 + 0);  // true
ctype_digit($inty2); // false
nickf
źródło
2
+1 dla Ciebie również (choć zastanawiam się, czy ten konkretny przypadek zostałby rozwiązany jaśniej przez przycięcie ciągu wejściowego).
Dominic Rodger
6
Ta metoda nie działa w przypadku ciągów nienumerycznych: is_int ("abc" +0) jest prawdą
Kai Pommerenke
1
To prawda, że ​​nie działa dla ciągów nienumerycznych ... co za is_int($inty + 0) && is_numeric($inty)(wiem, że jest to leniwe rozwiązanie, ale działa w większości zamiarów i celów ...
Alex Mantaut
Używanie juggingu typów spowoduje dość luźne sprawdzanie, gdzie ints mogą być reprezentowane na różne sposoby, nie jest to sprawdzanie stringów. Nie musisz też +0. Możesz po prostu + $ var.
jgmjgm
13

Prześlij na int. jeśli nadal ma tę samą wartość to int;

function my_is_int($var) {
  $tmp = (int) $var;
  if($tmp == $var)
       return true;
  else
       return false;
}
greg
źródło
2
Albo jeszcze krócej:return $var == (int) $var;
Al.G.
1
@ AI.G. Co się stanie, jeśli rzut się nie powiedzie
DR.
Jest to bardzo blisko, ale powinno unikać żonglowania typami, jeśli nie jest potrzebne. To zadziała, jeśli zmienna $ var to „123xxxx”.
jgmjgm
8
/**
 * Check if a number is a counting number by checking if it
 * is an integer primitive type, or if the string represents
 * an integer as a string
 */
function is_int_val($data) {
    if (is_int($data) === true) return true;
    if (is_string($data) === true && is_numeric($data) === true) {
        return (strpos($data, '.') === false);
    }
}

Źródło .

GmonC
źródło
zamiast rozpraszać mój kod małymi funkcjami użytkowymi, wolałbym mieć coś wbudowanego w php.
Rory
Te hacki też mi się nie podobają. Ale używając tego podejścia lub sugestii typu ctype Dominica, i tak zamkniesz całą implementację w metodzie. Używając php, zawsze mam klasę „Util”, która rozwiązuje te problemy.
GmonC,
elseifmoże być po prostu ifdlatego, że już wróciłeś w oświadczeniu powyżej.
rybo111
Nie ma też potrzeby zwracania fałszu na końcu.
rybo111
1
Jeśli $datajest obiektem, to zwróci null. Lepiej mieć return false;na końcu.
Theodore R. Smith
6

is_intOstatnio potrzebowałem solidnego . Uważam, że intval () jest zbyt nieprzewidywalny:

intval(array('foo', 'bar')) //returns 1 ?!?
intval("2dog") //returns 2 even though the value is definitely not an integer
intval("dog2") //also returns 2


Przeszedłem przez ten fragment w komentarzach do dokumentacji PHP, a po przetestowaniu obejmuje on prawie wszystko, co do niego wrzucisz:

function my_is_int($s) {
    return (is_numeric($s) ? intval($s) == $s : false);
}


my_is_int(2); //true
my_is_int("2"); //true
my_is_int(2.1); //false
my_is_int("2.1"); //false
my_is_int("dog"); //false
my_is_int("2dog"); //false
my_is_int("dog2"); //false
my_is_int(array('foo', 'bar')); //false
my_is_int(array(1)); //false


Ale uważaj:

my_is_int(2.0); //true
my_is_int("2.0"); //true
Costa
źródło
6

Jednym naprawdę czystym sposobem, którego lubię, jest ten. Rzucasz to dwukrotnie, najpierw do intśrodka, po drugie do środka string, a następnie do ścisłego porównania ===. Zobacz poniższy przykład:

$value === (string)(int)$value;

A teraz o twojej funkcji my_is_int, możesz zrobić coś takiego:

function my_is_int($value){ return $value === (string)(int)$value; }
my_is_int('2');  // true
my_is_int('2.1') // false
Jonathan Gagne
źródło
4
function my_is_int($var) {
    return preg_match('/^\d+$/', $var);
}
Michael Connor
źródło
1
Użyłem odmiany tego, zezwalając na sygnał numeryczny:'/^[-+]?[0-9]+$/'
Denilson Sá Maia
To jest to samo, co ctype_digit, ale dopuszcza również końcowy znak nowej linii.
jgmjgm
3

Używam tego:

function isInt($val){

    return (filter_var($val, FILTER_VALIDATE_INT) !== false && strpos($val, '-') === false);

}

var_dump (isInt("1"));
julesdude
źródło
3

Możesz po prostu sprawdzić liczbę, jeśli jest, to sprawdź, czy rzucanie ma podwójne, czy nie:

((is_numeric($var) && !is_double(1*$var)));

Tylko dla liczb dodatnich:

(is_numeric($var) && !is_double(1*$var)) && ($var >= 0)

Sprawdzanie:

$numbersToCheck = array("a", "-1", "1", "1.0", "1.2");

foreach ($numbersToCheck as $var) {
    echo $var . " is integer? ";var_dump((is_numeric($var) && !is_double(1*$var)));

    echo $var . " is a positive integer? ";var_dump((is_numeric($var) && !is_double(1*$var)) && ($var >= 0));
}

Wynik:

a is integer? bool(false)
a is a positive integer? bool(false)
-1 is integer? bool(true)
-1 is a positive integer? bool(false)
1 is integer? bool(true)
1 is a positive integer? bool(true)
1.0 is integer? bool(false)
1.0 is a positive integer? bool(false)
1.2 is integer? bool(false)
1.2 is a positive integer? bool(false)
Jordi Martínez
źródło
is_numeric () było tym, czego szukałem.
ccjjmartin
1
Aby mieć pewność, że tego właśnie chcesz, musisz przeczytać źródło PHP, ponieważ nie jest dobrze udokumentowane. Na przykład is_numeric akceptuje początkowe białe znaki, które nie są udokumentowane w podręczniku PHP. Należy również pamiętać, że liczby całkowite w łańcuchach, które są zbyt duże, aby można je było przedstawić za pomocą natywnej liczby int, są przekształcane do typu float.
jgmjgm
2

Spróbuj tego:

$string='12abc';
if ((int)$string==$string) var_dump((int)$string); else echo 'Invalid!';
// Outputs: Invalid!

$string='789';
if ((int)$string==$string) var_dump((int)$string); else echo 'Invalid!';
// Outputs: int 789

$string='345.00';
if ((int)$string==$string) var_dump((int)$string); else echo 'Invalid!';
// Outputs: 345

$string='123.01';
if ((int)$string==$string) var_dump((int)$string); else echo 'Invalid!';
// Outputs: Invalid!

Działa również, jeśli twój ciąg $ ma miejsca dziesiętne

Jack M.
źródło
Spowoduje to potraktowanie 123xxxx jako prawidłowego ciągu int.
jgmjgm
2

To zajmie się również liczbą ujemną

function myIsInt()
{
   return (is_numeric($var) AND (is_int($var) OR ctype_digit(trim($var, '-'))))
}
//'234-' => false
//'-234' => true
//'--234' => false
//'234' => true
wolakpaul
źródło
Nie rozumiem, dlaczego to zwróciło fałsz dla 234- lub --234, czy przetestowałeś to? To powróci do ----- 1234 ----
jgmjgm
2
function my_is_int($var){
    return is_numeric($var) && gettype($var+0)=='integer';
}
udziel słońca
źródło
2

Wymyśliłem sposób, którego nie mogłem nigdzie znaleźć, więc umieszczam go tutaj:

Bez zbędnych ceregieli jest to: ctype_digit((string) abs($input))

Przykład:

function means_int($input) {
    return ctype_digit((string) abs($input));
}

$list = array(
    0,
    '0',
    1,
    '1',
    1.1,
    '1.1',
    2.0,
    '2.0',  
    2.6,
    '2.6',
    -4,
    '-4',   
    -3.2,
    '-3.2',
    -30.02,
    '-30.02',   
    100.00,
    '100.00',   
);

foreach ($list as $x) {
    var_dump($x);
    var_dump(means_int($x));
    echo PHP_EOL;
}

Wyniki: (przypuszczam, że są zgodne z oczekiwaniami)

int(0)
bool(true)

string(1) "0"
bool(true)

int(1)
bool(true)

string(1) "1"
bool(true)

float(1.1)
bool(false)

string(3) "1.1"
bool(false)

float(2)
bool(true)

string(3) "2.0"
bool(true)

float(2.6)
bool(false)

string(3) "2.6"
bool(false)

int(-4)
bool(true)

string(2) "-4"
bool(true)

float(-3.2)
bool(false)

string(4) "-3.2"
bool(false)

float(-30.02)
bool(false)

string(6) "-30.02"
bool(false)

float(100)
bool(true)

string(6) "100.00"
bool(true)
Smuuf
źródło
abs rzutuje dane wejściowe z łańcucha na numeryczne. To to samo, co is_int (+ $ var).
jgmjgm
2

Może nie jest to najlepszy sposób na zrobienie tego. Ale możesz napisać to w jednej linii.

function my_is_int($input) {
    return intval($input).'' === $input.'';
}

Zgodnie z oczekiwaniami:

    my_is_int(1);     // TRUE
    my_is_int(-1);    // TRUE
    my_is_int(1.2);   // FALSE
    my_is_int("1");   // TRUE
    my_is_int("-1");  // TRUE
    my_is_int("1.2"); // FALSE
    my_is_int(0);     // TRUE
    my_is_int(null);  // FALSE

Mam cię:

    my_is_int(1.0);   // TRUE
    my_is_int("1.0"); // FALSE
mwallisch
źródło
Ten jest poprawny, o ile upewnisz się, że $ input jest typu string.
jgmjgm
2

Kilka lat później, ale na podstawie udzielonych tutaj odpowiedzi wymyśliłem rozwiązanie, które jest nieco dokładniejsze (szczególnie w przypadku wartości logicznych) i wydajniejsze (myślę) niż większość innych odpowiedzi:

function my_is_int($s) {
    return ctype_digit($s) || is_int($s);
}

Działa zgodnie z oczekiwaniami dla tych:

my_is_int(2);                   // true
my_is_int("2");                 // true
my_is_int(-2);                  // true
my_is_int(2.0);                 // false
my_is_int("2.0");               // false
my_is_int(2.1);                 // false
my_is_int("2.1");               // false
my_is_int("dog");               // false
my_is_int("2dog");              // false
my_is_int("dog2");              // false
my_is_int(array('foo', 'bar')); // false
my_is_int(array(1));            // false
my_is_int(true);                // false
my_is_int(false);               // false
my_is_int("true");              // false
my_is_int("false");             // false
my_is_int("0x101010");          // false

Może z wyjątkiem tych 2:

my_is_int(0x101010);            // true
my_is_int("-2");                // false
SharkWipf
źródło
bardzo dobrze. jeśli chciałbyś obsłużyć ciąg liczbowy ze znakiem minus, możesz zmienić na ctype_digits (preg_replace ('/ ^ - /', '', $ s)), chociaż zaczyna się to trochę rozwlekać. również 0x101010 jest liczbą int, więc nie jest to błąd, ale raczej „0x101010” może zostać uznane za niepoprawne. Jestem pewien, że ciągi binarne pasujące do binarnej notacji literału („0b11111”) również nie powiodłyby się
fbas
1

Co powiesz na:

function isIntStr($str) {
   return preg_match('/^(-?\d+)(?:\.0+)?$/', trim($str), $ms)
       && bcComp($ms[1], PHP_INT_MAX) <= 0
       && bcComp($ms[1], -PHP_INT_MAX - 1) >= 0;
}

Ta funkcja powinna zwracać prawdę tylko dla dowolnej liczby ciągu, która może być rzutowana na int z (int)lub intval()bez utraty czegokolwiek o znaczeniu matematycznym (np. Niezerowych po przecinku lub liczb poza zakresem liczb całkowitych PHP), akceptując rzeczy, które nie są matematycznie istotne (np. białe spacje, zera wiodące lub, po przecinku, wyłącznie zera).

Zwróci fałsz dla, '10.'ale nie dla '10.0'. Jeśli chcesz, '10.'aby była prawdziwa, możesz zmienić +po 0znaku w wyrażeniu regularnym na *.


źródło
1

Oto kod, którego użyłem, który wydaje się działać dobrze i nie ma żadnych problemów, które występują w wielu innych.

if (0 != strlen(str_replace(range(0, 9), '', $TestInt))) { print 'Not an integer!';}

Nie sprawdza kolejności itp., Więc nie jest przeznaczony dla ujemnych liczb całkowitych, ale z dodatkowym kodem, który można również zrobić przy użyciu innych pomysłów z góry. Może być również przystosowany do pracy z liczbami binarnymi array('0', '1')lub szesnastkowymi itp.

Dragonaire
źródło
To jest po prostu bardzo kosztowna ctype_digit.
jgmjgm
1

Zobacz. Konwertuje wartość $ val na liczbę całkowitą, a następnie sprawdza, czy oryginalna wartość $ val przekonwertowana na łańcuch jest IDENTYCZNA (===) - po prostu == nie będzie działać zgodnie z oczekiwaniami - na liczbę całkowitą val zamienioną na łańcuch.

function validInt($val, $min=null, $max=null) {
    $ival = intval($val);
    //echo "'$ival' '$val'<br>\n"; // Uncomment to see the comparisons done in below if block
    if(''.$ival !== ''.$val) {
        return false;
    }
    if($min !== null && $ival < $min)
        return false;
    if($max !== null && $ival > $max)
        return false;
    return true;
}

Jeśli nie sprawdzisz wartości ciągów, może to nie działać zgodnie z oczekiwaniami:

$nums = array(
    '1',
    '+1',
    '-1',
    '01',
    '1.0',
    '.0',
    '1.123',
    'a123',
    '0x101010',
    1,
    -1,
    01,
    1.0,
    .0,
    1.123,
    0x101010,
);
foreach($nums as $num) {
    if(validInt2($num))
        echo $num." - Valid integer.<br>\n";
    else
        echo $num." - Not a valid integer.<br>\n";
}

Wynik:

1 - Valid integer.
+1 - Not a valid integer.
-1 - Valid integer.
01 - Not a valid integer.
1.0 - Not a valid integer.
.0 - Not a valid integer.
1.123 - Not a valid integer.
a123 - Not a valid integer.
0x101010 - Not a valid integer.
1 - Valid integer.
-1 - Valid integer.
1 - Valid integer.
1 - Valid integer.
0 - Valid integer.
1.123 - Not a valid integer.
1052688 - Valid integer.

Powodem jest to, że nawet jeśli używasz liczby szesnastkowej (0x101010), ósemkowej (01) lub liczby całkowitej przechowywanej jako zmiennoprzecinkowa (1,0, 0,0), wewnętrznie wszystkie są przechowywane jako zmiennoprzecinkowe. Jeśli jednak użyjesz funkcji do sprawdzenia int przechowywanego jako ciąg, zadziała.

Joe
źródło
1
public static function isNumeric($value, $negativ = false) {
    return is_int($value) || is_string($value) && (
        ctype_digit($value) || (
            $negativ && $value{0} == '-' && ctype_digit(substr($value, 1))
        )
    );

    //alternativ:
    //return $value == (int) $value;
}
Volker
źródło
Brakuje sprawdź ten ciąg! == ''. Jeśli umieścisz w tym naprawdę długą liczbę całkowitą, zwróci ona również wartość true dla czegoś, co PHP rzutowałoby na float!
jgmjgm
1

Możesz użyć następującego warunku. Zauważ, że nie powinieneś używać! ==

$value = 12; // true
$value = '12'; // true
$value = 'abc'; // false
$value = 12.1; // false
$value = '12.1'; // false

if (!is_numeric($value) || (int) $value != (float) $value) {
    echo "false";
} else {
    echo "true";
}
Saman Shafigh
źródło
1

Działa idealnie! Mam nadzieję, że będzie ci to pomocne =)

$value = 1; // true
$value = '1'; // true
$value = '1.0'; // true
$value = ' 1'; // true
$value = '01'; // true

$value = -1; // true
$value = '-1'; // true
$value = '-1.0'; // true
$value = ' -1'; // true
$value = '-01'; // true

$value = PHP_INT_MIN; // true
$value = PHP_INT_MAX; // true
$value = 0x000001; // true

$value = 'a'; // false
$value = '1a'; // false
$value = 'a1'; // false
$value = 1.1; // false
$value = '1.1'; // false
$value = '--1'; // false
$value = []; // false
$value = [1,2]; // false
$value = true; // false
$value = false; // false
$value = null; // false
$value = 'NaN'; // false
$value = 'undefined'; // false

function isInt($value) {
    return is_numeric($value) && floatval(intval($value)) === floatval($value);
}
vietbq
źródło
1
Odpowiadając na stare pytanie, twoja odpowiedź byłaby znacznie bardziej przydatna dla innych użytkowników StackOverflow, gdybyś zawarł kontekst wyjaśniający, w jaki sposób twoja odpowiedź pomaga, szczególnie w przypadku pytania, które ma już zaakceptowaną odpowiedź. Zobacz: Jak napisać dobrą odpowiedź .
David Buck
0

Jeśli chcesz naprawdę wiedzieć, czy łańcuch jest prawidłową reprezentacją prawdziwej liczby całkowitej PHP ...

in_array($string, array_map('strval', range(PHP_INT_MIN, PHP_INT_MAX)), true)

Jednak nie można tego uruchomić, ponieważ zestaw jest zbyt duży (w tym przypadku nie zmieści się w pamięci, jeśli zamiast tego wykonasz pętlę, zajmie to zbyt wiele cykli procesora).

Być może możesz przeprowadzić wyszukiwanie binarne z porównaniem ciągów, jednak są lepsze sposoby.

Najprostsza istota:

strlen($string) <= max(strlen((string)PHP_INT_MIN), strlen((string)PHP_INT_MAX)) && $string === (string)(int)$string

Istnieją inne nietypowe sposoby podejścia do tego problemu, takie jak:

is_int(array_keys([$string => null])[0])

Możesz także porównać ciągi znaków, ale nadal będziesz musiał zrobić takie rzeczy, jak ctype_digit, sprawdzić, czy długość jest rozsądna (nie marnuj procesora przed wykonaniem takich rzeczy, jak ctype_digit) i trochę niezręcznej obsługi liczb ujemnych.

Zauważ, że zmienna filter_var nie zapewnia poprawnie, że łańcuch jest autentyczną reprezentacją liczby całkowitej PHP. Umożliwi to wiodący znak + i otaczające go białe znaki.

Wewnętrznie PHP używa funkcji "_zend_handle_numeric_str" do ścisłego porównania, ale nigdzie nie ujawnia tego bezpośrednio, stąd sztuczka z użyciem kluczy tablicowych (która używa jej do konwersji dowolnego ciągu będącego reprezentacją liczby całkowitej PHP na liczbę całkowitą PHP).

Jeśli chcesz, aby konwersja plików binarnych do iz PHP była bezpieczna, to jest to podejście.

Nie każdy może tego chcieć i może to być przypadek obsługi danych wejściowych użytkownika. filter_var nie jest na to zły i będzie całkiem bezpieczny w większości przypadków dla osób, które nie znają PHP.

Sprawdzenie długości, ctype_digit, a następnie sprawdzenie przekonwertowanej wartości, czy znajduje się w zakresie, jest również dość solidne dla danych wejściowych użytkownika. Bardziej złożone schematy mogą wymagać trim lub regex.

Problem z wieloma odpowiedziami tutaj w tym względzie polega na tym, że chociaż pytanie jest niejasne, odpowiedzi nie powinny być. Jeśli masz zamiar zaproponować rozwiązanie, powinieneś być w stanie dokładnie wyjaśnić, co będzie, a czego nie będziesz się spodziewać. Bez tego nie wiadomo, czy odpowiedź pasuje do pytania, czy jest bezpieczna. Podręcznik PHP nie zawsze pomaga, ponieważ nie wyjaśnia wszystkich zastrzeżeń dotyczących każdej z odpowiednich metod, które dostarcza. Rzeczy takie jak ctype_digit i is_int są bardzo niezawodne i łatwe do odczytania, ale szczegóły dotyczące is_numeric, filter_var i juggling (+ $ var) lub rzutowania (intval / floatval) są słabo udokumentowane.

To jest krówka PHP dla Ciebie. Ma niezliczoną liczbę schematów do interpretacji ciągów znaków jako liczb całkowitych, z niespójnościami. Najbardziej rygorystyczna metoda sprawdzania poprawności łańcucha liczb całkowitych nie jest bezpośrednio ujawniana użytkownikowi.

jgmjgm
źródło
0

Jeśli obsługujesz identyfikatory numeryczne z mysql i próbujesz narzucić walidację, aby była to poprawna wartość int niezerowa lub an, intale w formacie ciągu ( ponieważ mysql zawsze zwraca wszystko w formacie ciągu ), a nie NULL. Możesz użyć następujących. Jest to najbardziej odporny na błędy / ostrzeżenie / powiadomienie sposób zezwalania tylko na te, int/string-intsktóre znalazłem.

...
if(empty($id) || !is_scalar($id) || !ctype_digit($id)){
  throw("Invalid ID");
}
...
Mohd Abdul Mujib
źródło
0

Oto proste rozwiązanie, które wykorzystuje is_numeric , floatval i intval :

function is_string_an_int($string)
{
    if (is_string($string) === false)
    {
        //throw some kind of error, if needed
    }

    if (is_numeric($string) === false || floatval(intval($string)) !== floatval($string))
    {
        return false;
    }

    else
    {
        return true;
    }
}

Wyniki:

is_string_an_int('-1'); //true
is_string_an_int('-1.0'); //true
is_string_an_int('-1.1'); //false
is_string_an_int('0'); //true
is_string_an_int('0.0'); //true
is_string_an_int('0.1'); //false
is_string_an_int('1'); //true
is_string_an_int('1.0'); //true
is_string_an_int('1.1'); //false
is_string_an_int('' . PHP_INT_MAX); //true
is_string_an_int('foobar'); //false
is_string_an_int('NaN'); //false
is_string_an_int('null'); //false
is_string_an_int('undefined'); //false

Zauważ, że wartości większe niż PHP_INT_MAX mogą zwracać fałsz.

Pikamander2
źródło
-1

Można użyć is_numeric (), a następnie sprawdzić obecność „.” w ciągu (choć nie jest szczególnie wrażliwa na kulturę).

Alternatywnie użyj is_numeric (), a następnie rzutuj na double i zobacz, czy $ var == floor ($ var) (powinno zwrócić true, jeśli jest to liczba całkowita).

Paolo
źródło
Jest to jedyna odpowiedź, która rozpoznaje zmiany regionalne, a także zmienia sposób, w jaki PHP interpretuje i wyświetla liczby. Bądź bardzo ostrożny z setlocale i rozwiązaniami, które przyjmują założenia dotyczące separatorów.
jgmjgm