Как проверить, что строка является целым числом, а не двойным и т. Д.? - PullRequest
135 голосов
/ 06 января 2010

PHP имеет функцию intval(), которая преобразует строку в целое число. Однако я хочу заранее проверить, что строка является целым числом, чтобы я мог дать пользователю полезное сообщение об ошибке, если оно неверно. PHP имеет is_int(), но возвращает строку для строки типа "2".

PHP имеет функцию is_numeric(), но она вернет true, если число является двойным. Я хочу что-то, что будет возвращать false для двойного, но true для целого.

например:.

my_is_int("2") == TRUE
my_is_int("2.1") == FALSE

Ответы [ 24 ]

2 голосов
/ 14 октября 2014
function my_is_int($var){
    return is_numeric($var) && gettype($var+0)=='integer';
}
2 голосов
/ 03 сентября 2014

Это также позаботится об отрицательном числе

function myIsInt()
{
   return (is_numeric($var) AND (is_int($var) OR ctype_digit(trim($var, '-'))))
}
//'234-' => false
//'-234' => true
//'--234' => false
//'234' => true
2 голосов
/ 26 июня 2014

Попробуйте это:

$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!

Также работает, если ваша строка $ имеет десятичные знаки

2 голосов
/ 12 февраля 2016

Возможно, не самый эффективный способ сделать это. Но вы можете написать это в одну строку.

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

Как и ожидалось:

    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

Гоча:

    my_is_int(1.0);   // TRUE
    my_is_int("1.0"); // FALSE
1 голос
/ 06 апреля 2017

Несколько лет спустя, но, основываясь на ответах, приведенных здесь, я пришел к решению, которое немного более точно (в частности, по логическим значениям) и более эффективно (я думаю), чем большинство других ответов:

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

Работает, как ожидалось, для этих:

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

За исключением, может быть, для этих 2:

my_is_int(0x101010);            // true
my_is_int("-2");                // false
1 голос
/ 03 февраля 2015

Вы можете использовать следующее условие. Обратите внимание, что вы не должны использовать! ==

$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";
}
1 голос
/ 21 апреля 2015

Я придумал способ, который нигде не мог найти, поэтому я помещаю это сюда:

Без лишних слов это: ctype_digit((string) abs($input))

Пример:

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;
}

Результаты: (как и положено, я полагаю)

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)
1 голос
/ 11 ноября 2013

Как насчет:

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;
}

Эта функция должна возвращать true только для любого строкового числа, которое может быть приведено к int с помощью (int) или intval() без потери чего-либо математического значения (например, ненулевые значения после десятичной точки или числа вне целочисленного диапазона PHP) принимая то, что не является математически значимым (например, пробел; начальные нули или, после десятичной точки, исключительно нули).

Он вернет false для '10.', но не для '10.0'. Если вы хотите, чтобы значение '10.' было истинным, вы можете изменить + после 0 в регулярном выражении на *.

1 голос
/ 18 декабря 2013

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

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

Он не проверяет порядок и т. Д., Поэтому он предназначен не для отрицательных целых чисел, а с некоторым дополнительным кодом, который также может быть выполнен с использованием некоторых других идей, приведенных выше. Он также может быть адаптирован для работы с двоичными array('0', '1') или шестнадцатеричными числами и т. Д.

1 голос
/ 20 декабря 2013

Смотрите это. Преобразует $ val в целое число, а затем проверяет, является ли исходный $ val, преобразованный в строку, IDENTICAL (===) - просто == не будет работать должным образом - в целочисленное значение val, преобразованное в строку.

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;
}

Если вы не проверяете строковые значения, они могут работать не так, как вы ожидаете:

$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";
}

Выход:

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.

Причина в том, что даже если вы используете шестнадцатеричное (0x101010), восьмеричное (01) или целое число, хранящееся как float (1.0, 0.0), внутренне все они хранятся как float. Однако если вы используете функцию для проверки на наличие int, хранящегося в виде строки, она будет работать.

...