จะตรวจสอบได้อย่างไรว่าสตริงนั้นเป็น int แต่ไม่ใช่ double เป็นต้น


155

PHP มีintval()ฟังก์ชั่นที่จะแปลงสตริงเป็นจำนวนเต็ม อย่างไรก็ตามฉันต้องการตรวจสอบว่าสตริงเป็นจำนวนเต็มล่วงหน้าเพื่อให้ฉันสามารถให้ข้อความแสดงข้อผิดพลาดที่เป็นประโยชน์กับผู้ใช้หากมันผิด PHP มีแต่ผลตอบแทนที่เป็นเท็จสำหรับสายเช่นis_int()"2"

PHP มีis_numeric()ฟังก์ชั่น แต่มันจะคืนค่าจริงถ้าจำนวนนั้นเป็นสองเท่า ฉันต้องการบางสิ่งที่จะส่งกลับค่าเท็จสำหรับสองเท่า แต่จริงสำหรับ int

เช่น:

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

6
ควรปฏิบัติกับ "2.0" อย่างไร?
nickf

คำตอบ:


183

วิธีการเกี่ยวกับการใช้งานctype_digit?

จากคู่มือ:

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

ตัวอย่างด้านบนจะแสดงผล:

สตริง 1820.20 ไม่มีตัวเลขทั้งหมด
สตริง 10002 ประกอบด้วยตัวเลขทั้งหมด
สตริง wsl! 12 ไม่ประกอบด้วยตัวเลขทั้งหมด

วิธีนี้จะใช้งานได้หากอินพุตของคุณเป็นสตริงเสมอ:

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

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

ถ้าใส่ของคุณอาจเป็นชนิดintแล้วรวมกับctype_digitis_int

หากคุณสนใจเกี่ยวกับตัวเลขที่ติดลบแล้วคุณจะต้องตรวจสอบข้อมูลสำหรับก่อนหน้านี้-และถ้าเป็นเช่นนั้นการโทรctype_digitบนsubstrของสายป้อน สิ่งนี้จะทำ:

function my_is_int($input) {
  if ($input[0] == '-') {
    return ctype_digit(substr($input, 1));
  }
  return ctype_digit($input);
}

7
ตัวเลขติดลบ?
Anurag

1
@Anurag, แก้ไขใน (แม้ว่าคุณสนใจสิ่งนี้จริง ๆ , regex นั้นอาจจะง่ายกว่า)
โดมินิกร็อดเจอร์

4
หากคุณต้องการที่จะตรวจสอบจำนวนเต็มลบเพิ่มการใช้งานของเอบีเอส ()เช่นดังนั้นแทนเพียงctype_digit(abs($str)) ctype_digit
Enchance

3
abs('definitelynotanint') === 0@enchance ยิ่งไปกว่านั้นctype_digitรับสายเท่านั้น
Klesun

สิ่งนี้ไม่ถูกต้อง จำนวนเต็มขนาดใหญ่ใน PHP เป็นสองเท่า!
jgmjgm

91

filter_var ควรทำ:

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

แต่

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

หากคุณต้องการให้ Booleans เป็นค่าตอบแทนให้ห่อเป็นฟังก์ชันเช่น

function validatesAsInt($number)
{
    $number = filter_var($number, FILTER_VALIDATE_INT);
    return ($number !== FALSE);
}

2
ฉันชอบคำตอบส่วนใหญ่ แต่ฉันคิดว่าอันนี้สวยที่สุด
Ian Dunn

6
@grenoult 3v4l.org/qVRRSให้ค่า 0 สำหรับสตริงและจำนวนเต็มดังนั้นไม่แน่ใจว่าทำไมคุณถึงคิดว่ามันใช้งานไม่ได้ คุณกำลังเปรียบเทียบผลลัพธ์กับ==บางทีหรือไม่
Gordon

1
@Gordon ความผิดพลาดของฉันจริง ๆ แล้วฉันเปรียบเทียบกับif 3v4l.org/IAvCF
Guillaume Renoult

สิ่งนี้จะทำบางสิ่งที่แปลกเช่นการคืนค่าจริงสำหรับ "+123" มันลดลงโดยที่มันหมายถึงการคืน int ที่แท้จริง แต่ก็อาจจะไม่ใช่สิ่งที่คนต้องการซึ่งเป็นการตรวจสอบอย่างเข้มงวด
jgmjgm

@ MohammedRédaOUASSINI OP ขอให้ตรวจสอบความถูกต้องของสตริงไม่ใช่ลอย มันจะทำงานถ้าคุณผ่านใน '-1.0' (สตริง) มันจะไม่ทำงานถ้าคุณผ่านใน -1.0 (ลอย) แต่นั่นไม่ใช่ความต้องการที่จะเริ่มต้นด้วย ดู3v4l.org/bOX6X
Gordon

20

+1 ถึงคำตอบของ Dominic (โดยใช้ctype_digit) อีกวิธีที่คุณสามารถทำได้คือใช้การบีบบังคับประเภท:

$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

2
+1 ให้คุณด้วย (แม้ว่าฉันจะสงสัยว่ากรณีนั้นจะได้รับการจัดการอย่างชัดเจนยิ่งขึ้นโดยการตัดแต่งสตริงอินพุต)
Dominic Rodger

6
วิธีนี้ใช้ไม่ได้กับสตริงที่ไม่ใช่ตัวเลข: is_int ("abc" +0) เป็นจริง
Kai Pommerenke

1
จริงมันใช้งานไม่ได้กับสตริงที่ไม่ใช่ตัวเลข ... เป็นเรื่องเกี่ยวกับอะไรis_int($inty + 0) && is_numeric($inty)(ฉันรู้ว่ามันเป็นวิธีแก้ปัญหาที่ขี้เกียจ แต่ทำงานเพื่อจุดประสงค์และจุดประสงค์ส่วนใหญ่ ...
Alex Mantaut

การใช้การจิกประเภทจะทำให้การตรวจสอบค่อนข้างหลวมซึ่ง ints สามารถแสดงได้ในรูปแบบของสตริงทุกชนิดไม่ใช่การตรวจสอบสตริง คุณไม่จำเป็นต้องมีค่า +0 คุณสามารถเพียง + $ var
jgmjgm

13

ส่งไปที่ int ถ้ามันยังคงมีค่าเหมือนกันมันคือ int;

function my_is_int($var) {
  $tmp = (int) $var;
  if($tmp == $var)
       return true;
  else
       return false;
}

2
หรือสั้นกว่า:return $var == (int) $var;
อัลจี

1
@ AI.G จะเกิดอะไรขึ้นถ้านักแสดงล้มเหลว
DR

อยู่ใกล้มากควรหลีกเลี่ยงการเล่นกลแบบแม้ว่าจะไม่จำเป็นก็ตาม สิ่งนี้จะใช้งานได้ถ้า $ var คือ "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);
    }
}

แหล่ง


แทนที่จะกระจายโค้ดของฉันด้วยฟังก์ชั่นยูทิลิตี้เล็ก ๆ น้อย ๆ ฉันควรมีบางอย่างที่ติดตั้งไว้ใน PHP
Rory

ฉันไม่ชอบแฮ็กเหล่านี้เช่นกัน แต่การใช้วิธีการนี้หรือคำแนะนำ ctype โดย Dominic คุณจะต้องสรุปการใช้งานทั้งหมดในวิธีการ เมื่อใช้ php ฉันมักจะมีคลาส "Util" เพื่อแก้ไขปัญหาเหล่านี้
GmonC

elseifอาจเป็นifเพราะคุณได้กลับมาแล้วในคำสั่งด้านบน
rybo111

ยังไม่จำเป็นต้องส่งคืนเท็จในตอนท้าย
rybo111

1
หากเป็นวัตถุนี้จะกลับมา$data nullดีกว่ามีreturn false;ที่สิ้นสุด
Theodore R. Smith

6

มีความต้องการที่แข็งแกร่งis_intเมื่อเร็ว ๆ นี้ ฉันพบ intval () คาดเดาไม่ได้เกินไป:

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


มาถึงตัวอย่างนี้ในความคิดเห็นเอกสาร PHP และหลังจากการทดสอบมันครอบคลุมเกือบทุกอย่างที่คุณโยนมัน:

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


แต่ระวัง:

my_is_int(2.0); //true
my_is_int("2.0"); //true

6

วิธีหนึ่งที่สะอาดจริงๆที่ฉันชอบใช้ก็คือ คุณโยนมันสองครั้งแรกในintประการที่สองในแล้วคุณเข้มงวดเปรียบเทียบstring ===ดูตัวอย่างด้านล่าง:

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

ตอนนี้เกี่ยวกับฟังก์ชั่นของคุณ my_is_int คุณสามารถทำสิ่งนี้:

function my_is_int($value){ return $value === (string)(int)$value; }
my_is_int('2');  // true
my_is_int('2.1') // false

4
function my_is_int($var) {
    return preg_match('/^\d+$/', $var);
}

1
ฉันใช้ความหลากหลายของสิ่งนี้ยอมให้สัญญาณหมายเลข:'/^[-+]?[0-9]+$/'
Denilson Sá Maia

นี่เป็นเช่นเดียวกับ ctype_digit และยังอนุญาตให้ขึ้นบรรทัดใหม่
jgmjgm

3

ฉันใช้อันนี้:

function isInt($val){

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

}

var_dump (isInt("1"));

3

คุณสามารถตรวจสอบหมายเลขถ้ามันเป็นแล้วตรวจสอบกว่าการคัดเลือกนักแสดงจะได้รับสองครั้งหรือไม่:

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

สำหรับตัวเลขที่เป็นบวก:

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

ตรวจสอบมัน:

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

เอาท์พุท:

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)

is_numeric () เป็นสิ่งที่ฉันกำลังมองหา
ccjjmartin

1
เพื่อให้แน่ใจว่านี่คือสิ่งที่คุณต้องการคุณจะต้องอ่านแหล่งที่มาของ PHP เนื่องจากไม่ได้มีการบันทึกไว้อย่างดี ตัวอย่างเช่น is_numeric ยอมรับช่องว่างนำหน้าซึ่งไม่ใช่สิ่งที่บันทึกไว้ในคู่มือ PHP คุณควรทราบว่าจำนวนเต็มสตริงที่มีขนาดใหญ่เกินไปที่จะแสดงด้วย int ดั้งเดิมจะถูกแปลงเป็นลอย
jgmjgm

2

ลองสิ่งนี้:

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

ยังทำงานได้ถ้า $ string ของคุณมีทศนิยม


สิ่งนี้จะถือว่า 123xxxx เป็นสตริง int ที่ถูกต้อง
jgmjgm

2

นี้จะดูแลจำนวนลบเช่นกัน

function myIsInt()
{
   return (is_numeric($var) AND (is_int($var) OR ctype_digit(trim($var, '-'))))
}
//'234-' => false
//'-234' => true
//'--234' => false
//'234' => true

ฉันไม่เข้าใจว่าทำไมสิ่งนี้ถึงส่งกลับค่าเท็จเป็น 234- หรือ --234 คุณลองทดสอบดูหรือไม่? สิ่งนี้จะกลับมาเป็นจริงสำหรับ ----- 1234 ----
jgmjgm


2

ฉันคิดค้นวิธีที่ฉันไม่สามารถหาได้ทุกที่ดังนั้นฉันจึงวางมันไว้ที่นี่:

โดยไม่ต้องกังวลใจต่อไปนี้เป็น: 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)

abs กำลังส่งอินพุตจากสตริงไปเป็นตัวเลข เหมือนกับ is_int (+ $ var)
jgmjgm

2

อาจไม่ใช่วิธีที่มีประสิทธิภาพที่สุดของการทำมัน แต่คุณสามารถเขียนมันในหนึ่งบรรทัด

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

Gotcha:

    my_is_int(1.0);   // TRUE
    my_is_int("1.0"); // FALSE

อันนี้ถูกต้องตราบใดที่คุณมั่นใจว่า $ input เป็นสตริงประเภท
jgmjgm

2

ไม่กี่ปีที่ผ่านมา แต่จากคำตอบที่ให้ไว้ที่นี่ฉันคิดวิธีแก้ปัญหาที่แม่นยำกว่าเล็กน้อย (โดยเฉพาะใน booleans) และมีประสิทธิภาพมากขึ้น (ฉันคิดว่า) มากกว่าคำตอบอื่น ๆ ส่วนใหญ่:

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

ดีมาก. หากคุณต้องการที่จะจัดการกับสตริงตัวเลขที่มีเครื่องหมายลบคุณสามารถเปลี่ยนเป็น ctype_digits (preg_replace ('/ ^ - /', '', $ s)) ถึงแม้ว่ามันจะเริ่มลมแรงสักหน่อย นอกจากนี้ 0x101010 ก็เป็น int ดังนั้นจึงไม่ใช่ข้อผิดพลาด แต่แทนที่จะเป็น "0x101010" อาจถือว่าไม่ถูกต้องและฉันแน่ใจว่าสตริงไบนารี่ที่ตรงกับสัญพจน์ตัวอักษรไบนารี ("0b11111") จะล้มเหลวเช่นกัน
fbas

1

เกี่ยวกับ:

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

ฟังก์ชันนี้ควรคืนค่าจริงสำหรับหมายเลขสตริงใด ๆ ที่สามารถส่งไปยัง int โดยมี(int)หรือintval()ไม่มีการสูญเสียความสำคัญทางคณิตศาสตร์ใด ๆ (เช่นไม่ใช่ศูนย์หลังจุดทศนิยมหรือตัวเลขที่อยู่นอกช่วงจำนวนเต็มของ PHP) ในขณะที่ยอมรับสิ่งต่าง ๆ (เช่น whitespace ศูนย์นำหน้าหรือหลังจุดทศนิยมศูนย์เฉพาะ)

มันจะกลับเท็จแต่ไม่ได้สำหรับ'10.' '10.0'หากคุณต้องการ'10.'ที่จะเป็นจริงคุณสามารถเปลี่ยน+หลังจากที่ในการแสดงออกปกติไป0*


1

นี่คือรหัสบางส่วนที่ฉันใช้ซึ่งดูเหมือนว่าจะทำงานได้ดีและไม่มีปัญหาใด ๆ ที่คนอื่นทำ

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

มันไม่ได้ตรวจสอบคำสั่งซื้อ ฯลฯ ดังนั้นจึงไม่ได้มีความหมายสำหรับจำนวนเต็มลบ แต่ด้วยรหัสเพิ่มเติมบางอย่างที่สามารถทำได้เช่นกันโดยใช้แนวคิดอื่นจากด้านบน นอกจากนี้ยังสามารถดัดแปลงให้ทำงานกับไบนารีarray('0', '1')หรือฐานสิบหกได้เช่นกัน


นี่เป็นเพียง ctype_digit ที่มีราคาแพงมาก
jgmjgm

1

ดูนี่. แปลง $ 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.

เหตุผลที่เป็นแม้ว่าคุณจะใช้ hex (0x101010), octal (01) หรือจำนวนเต็มเก็บไว้เป็นลอย (1.0, 0.0) ภายในทั้งหมดจะถูกเก็บไว้เป็นลอย อย่างไรก็ตามหากคุณใช้ฟังก์ชั่นเพื่อตรวจสอบ int ที่เก็บไว้เป็นสตริงมันจะทำงาน


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

มันขาดการตรวจสอบสตริงที่! == '' ถ้าคุณใส่จำนวนเต็มยาว ๆ ลงไปมันจะคืนค่าจริงสำหรับบางสิ่งที่ PHP จะส่งให้ลอยตัว!
jgmjgm

1

คุณสามารถใช้เงื่อนไขต่อไปนี้ สังเกตว่าคุณไม่ควรใช้! ==

$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

มันทำงานได้อย่างสมบูรณ์แบบ! หวังว่ามันจะเป็นประโยชน์กับคุณ =)

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

1
เมื่อตอบคำถามเก่าคำตอบของคุณจะมีประโยชน์มากขึ้นสำหรับผู้ใช้ StackOverflow รายอื่นหากคุณรวมบริบทเพื่ออธิบายว่าคำตอบของคุณช่วยได้อย่างไรโดยเฉพาะอย่างยิ่งสำหรับคำถามที่มีคำตอบที่ยอมรับแล้ว ดู: ฉันจะเขียนคำตอบที่ดีได้อย่างไร
David Buck

0

ถ้าคุณต้องการทราบว่าสตริงเป็นตัวแทนที่ถูกต้องของ PHP จำนวนเต็มจริงหรือไม่

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

อย่างไรก็ตามนี่เป็นไปไม่ได้ที่จะเรียกใช้เนื่องจากชุดมีขนาดใหญ่เกินไป (จะไม่พอดีกับหน่วยความจำในกรณีนี้หากคุณวนซ้ำแทนจะใช้รอบ CPU มากเกินไป)

คุณอาจทำการค้นหาแบบไบนารีด้วยการเปรียบเทียบสตริงอย่างไรก็ตามมีวิธีที่ดีกว่า

สิ่งที่ง่ายที่สุด:

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

มีวิธีผิดปกติอื่น ๆ ที่จะเข้าใกล้เช่น:

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

คุณยังสามารถทำการเปรียบเทียบสตริงได้ แต่คุณจะต้องทำสิ่งต่าง ๆ เช่น ctype_digit ตรวจสอบความยาวที่เหมาะสม (อย่าเสีย CPU ก่อนทำสิ่งต่าง ๆ เช่น ctype_digit) และจัดการตัวเลขที่ไม่เหมาะสมบางอย่าง

โปรดทราบว่า filter_var ยืนยันอย่างไม่ถูกต้องว่าสตริงเป็นตัวแทนของจำนวนเต็ม PHP อย่างแท้จริง จะอนุญาตให้มีการนำหน้า + และช่องว่างโดยรอบ

ภายใน PHP ใช้ฟังก์ชั่น "_zend_handle_numeric_str" เพื่อการเปรียบเทียบที่เข้มงวด แต่มันไม่ได้เปิดเผยสิ่งนี้โดยตรงทุกที่ดังนั้นเคล็ดลับการใช้คีย์อาร์เรย์ (ซึ่งใช้ในการแปลงสตริงใด ๆ ที่เป็นตัวแทนของจำนวนเต็ม PHP เป็นจำนวนเต็ม PHP)

หากคุณต้องการแปลงที่ปลอดภัยแบบไบนารีไปและกลับจาก PHP นี่คือแนวทางที่จะทำ

ไม่ใช่ทุกคนที่อาจต้องการและอาจเป็นกรณีของการจัดการอินพุตของผู้ใช้ filter_var ไม่ได้เลวร้ายเกินไปสำหรับสิ่งนั้นและจะค่อนข้างปลอดภัยในกรณีส่วนใหญ่สำหรับผู้ที่เพิ่งเริ่มใช้ PHP

การตรวจสอบความยาว ctype_digit จากนั้นการตรวจสอบค่าที่แปลงแล้วซึ่งอยู่ในช่วงนั้นค่อนข้างแข็งสำหรับการป้อนข้อมูลของผู้ใช้ แผนการที่ซับซ้อนมากขึ้นอาจต้องการตัดหรือ regex

ปัญหาที่มีคำตอบมากมายในที่นี้คือในขณะที่คำถามนั้นคลุมเครือคำตอบก็ไม่ควร หากคุณกำลังจะเสนอวิธีแก้ปัญหาคุณควรจะสามารถอธิบายได้อย่างชัดเจนว่าอะไรจะเกิดขึ้นและไม่คาดหวัง หากปราศจากสิ่งนั้นก็ไม่มีการบอกถ้าคำตอบตรงกับคำถามหรือปลอดภัย คู่มือ PHP ไม่ได้ช่วยเสมอไปเพราะไม่ได้อธิบายคำเตือนทั้งหมดสำหรับวิธีการที่เกี่ยวข้องแต่ละรายการ สิ่งต่าง ๆ เช่น ctype_digit และ is_int มีความน่าเชื่อถือและง่ายต่อการคาดเดา แต่ข้อมูลจำเพาะของ is_numeric, filter_var และการเล่นปาหี่ (+ $ var) หรือการคัดเลือก (intval / floatval) มีการจัดทำเอกสารไม่ดี

นี่คือ PHP เหลวไหลสำหรับคุณ มันมีจำนวนสกีมาจำนวนมากสำหรับการตีความสตริงเป็นจำนวนเต็มโดยมีความไม่สอดคล้องกัน วิธีที่เข้มงวดที่สุดในการตรวจสอบความถูกต้องของสตริงจำนวนเต็มไม่ได้ถูกเปิดเผยต่อผู้ใช้โดยตรง


0

หากคุณมีการจัดการรหัสตัวเลขจาก MySQL และมีความพยายามที่จะกำหนดในการตรวจสอบเพื่อให้เป็นศูนย์ที่ถูกต้องไม่ใช่intหรือintแต่ในรูปแบบสตริง ( เป็น MySQL เสมอกลับทุกอย่างในรูปแบบสตริง ) NULLและไม่ใช่ คุณสามารถใช้สิ่งต่อไปนี้ นี่เป็นวิธีพิสูจน์ข้อผิดพลาด / เตือน / แจ้งให้ทราบล่วงหน้ามากที่สุดเพื่ออนุญาตเฉพาะint/string-intsสิ่งที่ฉันพบ

...
if(empty($id) || !is_scalar($id) || !ctype_digit($id)){
  throw("Invalid ID");
}
...

0

นี่เป็นวิธีง่ายๆที่ใช้is_numeric , floatvalและ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;
    }
}

ผล:

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

โปรดทราบว่าค่าที่มากกว่า PHP_INT_MAX อาจส่งคืนค่าเท็จ


-1

สามารถใช้ is_numeric () จากนั้นตรวจสอบว่ามี "" อยู่หรือไม่ ในสตริง (โดยเฉพาะอย่างยิ่งไม่ไวต่อวัฒนธรรมแม้ว่า)

หรือใช้ is_numeric () จากนั้นส่งไปยัง double และดูว่า $ var == floor ($ var) (ควรกลับจริงถ้าเป็นจำนวนเต็ม)


นี่เป็นคำตอบเดียวที่ตระหนักถึงการเปลี่ยนแปลงสถานที่นอกจากนี้ยังเปลี่ยนวิธีการตีความ PHP และหมายเลขผลลัพธ์ ระมัดระวังด้วย setlocale และวิธีแก้ปัญหาที่ทำให้สมมติฐานเกี่ยวกับตัวคั่น
jgmjgm
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.