2010-01-06 67 views
100

PHP有一個intval()函數可以將字符串轉換爲整數。不過,我想事先檢查該字符串是否爲整數,以便在錯誤的情況下向用戶提供有用的錯誤消息。 PHP有is_int(),但對於字符串"2"返回false。如何檢查一個字符串是一個int,但不是double等?

PHP有is_numeric()函數,但如果數字是雙精度值,則返回true。我想要的東西會返回false爲雙,但真正的一個int。

例如爲:

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

「2.0」應該如何處理? – nickf 2010-01-06 10:35:53

回答

128

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

上面的例子將輸出:

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

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

如果輸入:

 
The string 1820.20 does not consist of all digits. 
The string 10002 consists of all digits. 
The string wsl!12 does not consist of all digits. 

這隻會如果輸入始終是一個字符串工作可能是int類型,然後將ctype_digit與組合。

如果您關心的是負數,那麼您需要檢查前面的-的輸入,如果是這樣,請在輸入字符串的substr上調用ctype_digit。像這樣的事情會做到這一點:

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

負數? – Anurag 2010-01-06 10:51:34

+1

@Auurag,編輯(雖然如果你真的關心這個東西,一個正則表達式可能更簡單)。 – 2010-01-06 11:14:25

+4

如果您想檢查負整數,請像使用'ctype_digit(abs($ str))'而不只是'ctype_digit'那樣添加** abs()**的用法。 – enchance 2012-06-13 20:10:00

-2

既可以使用is_numeric()來然後檢查的存在 「」在字符串中(不是特別對文化敏感)。

或者使用is_numeric()然後將其轉換爲double並查看$ var == floor($ var)(如果它是整數,則返回true)。

+0

這是識別語言環境變化的唯一答案,也會改變PHP解釋和輸出數字的方式。對setlocale和對分隔符作出假設的解決方案要非常小心。 – jgmjgm 2017-12-11 19:11:11

6
/** 
* 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); 
    } 
} 

Source

+0

而不是分散我的代碼與小實用功能,我寧願有一些內置到PHP。 – Rory 2010-01-06 10:36:06

+0

我不喜歡這些黑客。但是使用Dominic的這種方法或者ctype建議,你將會在方法中封裝所有的實現。在使用php時,我總是有一個「Util」類來解決這些問題。 – GmonC 2010-01-06 13:53:40

+0

'elseif'可以是'if',因爲您已經在上面的語句中返回。 – rybo111 2015-06-08 08:39:04

14

+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(雖然我想知道是否通過修剪輸入字符串更清楚地處理該特定情況)。 – 2010-01-06 10:38:58

+5

此方法不適用於非數字字符串:is_int(「abc」+0)爲真 – 2013-01-29 18:07:37

+1

確實,它對於非數字字符串不起作用... 關於'is_int($ inty + 0) && is_numeric($ inty)'(我知道這是一個懶惰的解決方案,但適用於大多數意圖和目的...... – 2017-07-14 00:28:34

65

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 

如果你只是想布爾值作爲返回值,將它包裝成一個函數,例如

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

我喜歡大多數答案,但我認爲這是最優雅的 – 2011-08-20 19:09:01

+0

這不適用於0. – 2015-11-04 04:55:04

+3

@grenoult https ://3v4l.org/qVRRS爲字符串和整數提供了int 0,所以不知道爲什麼你認爲它不起作用。你是否將結果與'=='進行比較? – Gordon 2015-11-04 10:58:34

11

將它轉換爲int。 如果它的int值仍然相同;

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

甚至更​​短:'返回$ var ==(int)$ var;' – 2015-08-17 08:54:54

+1

@ AI.G。如果演員失敗會發生什麼 – 2015-09-14 10:24:01

+0

這非常接近,應該避免類型雜耍,儘管如果不需要。這將工作,如果$ var是「123xxxx」。 – jgmjgm 2017-12-11 18:12:42

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

我使用了這個變體,允許數字信號:''/^[ - +]?[0-9] + $ /'' – 2014-10-14 21:03:20

+0

這與ctype_digit相同,它也允許尾隨換行符。 – jgmjgm 2017-12-11 18:15:58

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 
3

I'm使用這一個:

function isInt($val){ 

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

} 

var_dump (isInt("1")); 
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; 
} 

此功能只能用於任何串號返回true,可以定投與(int)intval()爲int不失數學意義什麼(如小數點後的非零或PHP整數範圍之外的數字),同時接受不具有數學意義的事物(例如空白;前導零;或者在小數點後面,僅包含零)。

,將返回False爲'10.'而不是'10.0'。如果您希望'10.'爲true,則可以將0之後的+更改爲*

1

這裏是一些代碼,我使用的是似乎運作良好,並沒有任何的,許多人做的問題。

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

它不檢查順序等因此不是爲負整數但可以使用一些其他的想法從上面可以做,以及一些附加碼。它也可以適應二進制array('0', '1')或十六進制數以及等

+0

這只是一個非常昂貴的ctype_digit。 – jgmjgm 2017-12-11 19:07:33

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. 

原因是即使您使用十六進制(0x101010) ,八進制(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; 
} 
+0

它缺少一個檢查字符串!==''。如果你把一個非常長的整數放到這裏,它也會返回true來處理一些PHP會拋出的東西! – jgmjgm 2017-12-11 19:09:23

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! 

同樣工作,如果你的$字符串有小數

+0

這會將123xxxx視爲有效的int字符串。 – jgmjgm 2017-12-11 18:16:40

2

這會照顧負數,以及

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

我不明白爲什麼這會返回234或-234的錯誤,你測試了嗎?這將返回真正的----- 1234 ---- – jgmjgm 2017-12-11 18:29:32

1
function my_is_int($var){ 
    return is_numeric($var) && gettype($var+0)=='integer'; 
} 
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

我想出了一個辦法我找不到任何地方,所以我把它在這裏!

事不宜遲那就是: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; 
} 

結果:(如預期的,我suppos E)

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) 
+0

abs正在將輸入從字符串轉換爲數字。這與is_int(+ $ var)相同。 – jgmjgm 2017-12-11 19:06:01

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) 
+0

is_numeric()是我在找的東西。 – ccjjmartin 2017-09-26 22:16:36

+1

爲了確保這是你想要的,你需要閱讀PHP源代碼,因爲它沒有很好的文檔。例如,is_numeric接受領先的空白,這不是PHP手冊中記錄的內容。您還應該記住,太大而不能用本地int表示的字符串整數會被轉換爲浮點型。 – jgmjgm 2017-12-11 19:00:01

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 

疑難雜症:

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

這個是正確的,只要你確保$ input是字符串類型即可。 – jgmjgm 2017-12-11 18:30:28

1

幾年較晚,但基於這裏給出的答案,我想出了一個解決方案,它更爲精準(上布爾值,尤其是)和更有效的(我覺得)比大多數其他答案:

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 
+0

這不會使用一個非常長的int字符串。 – jgmjgm 2017-12-11 18:31:16

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,檢查長度是合理的(不要浪費這樣搞ctype_digit之前CPU),並有負數有些彆扭處理。

請注意,filter_var 不會正確聲明一個字符串是真正的PHP整數表示。它將允許領先的+和周圍的空白。

內部PHP使用函數「_zend_handle_numeric_str」進行嚴格比較,但它並不直接將其暴露在任何地方,因此使用數組鍵的技巧(使用它將任何字符串轉換爲PHP整數表示形式PHP整數)。

如果您希望進行PHP和PHP的二進制安全轉換,則需要採取這種方法。

不是每個人都可能想的是,它可能是處理用戶輸入的情況下。 filter_var是不是也太糟糕,將在大多數情況下,人們新的PHP相當安全。

長度檢查,ctype_digit,然後檢查轉換值,它在一個範圍內對於用戶輸入也是相當穩固的。更復雜的方案可能需要修剪或正則表達式。

在這方面很多答案的問題是,雖然問題是模糊的,答案不應該是。如果你要提出一個解決方案,你應該能夠解釋到底是什麼會和不會的期望。沒有這些,就不知道答案是否符合問題或是否安全。 PHP手冊並不總是有幫助,因爲它沒有解釋它提供的每種相關方法的所有注意事項。諸如ctype_digit和is_int之類的東西非常可靠且易於預測,但is_numeric,filter_var和juggling(+ $ var)或casting(intval/floatval)的細節記錄很差。

這是你的PHP軟糖。它有大量的模式將字符串解釋爲整數,但不一致。驗證整數字符串的最嚴格的方法不直接暴露給用戶。

相關問題