文字列がintであってdoubleではないことなどを確認する方法は?


155

PHPには、intval()文字列を整数に変換する関数があります。ただし、文字列が整数であることを事前に確認したいので、間違っている場合にユーザーに役立つエラーメッセージを表示できます。PHPにはis_int()がありますが、などの文字列に対してはfalseを返します"2"

PHPにはis_numeric()関数がありますが、数値がdoubleの場合はtrueを返します。doubleの場合はfalseを返し、intの場合はtrueを返すようなものが必要です。

例えば:

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_digitsubstr入力文字列の。このような何かがそれをします:

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

7
負の数?
Anurag

1
@Anurag、編集済み(ただし、これに本当に関心がある場合は、正規表現の方がおそらく簡単です)。
ドミニクロジャー2010年

4
あなたは、負の整数のチェックの使用追加したい場合は腹筋を()ので、のようなctype_digit(abs($str))だけではなくctype_digit
2012年

3
@enchance abs('definitelynotanint') === 0。さらに、ctype_digit文字列のみを受け取ります
Klesun

これは正しくありません。PHPの大きな整数はdoubleです!
jgmjgm 2017

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

戻り値としてブール値だけが必要な場合は、それを関数にラップします。たとえば、

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

2
私はほとんどの答えが好きですが、これが最もエレガントだと思います。
Ian Dunn

6
@grenoult 3v4l.org/qVRRSは文字列と整数にint 0を与えるので、なぜ機能しないと思うかわかりません。結果を==多分と比較していますか?
Gordon

1
@Gordon私の間違い、私は確かにif 3v4l.org/IAvCF
Guillaume Renoult

これは、「+ 123」に対してtrueを返すなど、いくつかの奇妙なことを行います。それは本当のintを返すことを意図していることで緩和されますが、それでも厳密なintチェックである人々が望むものではないかもしれません。
jgmjgm 2017

@MohammedRédaOUASSINIOPは、浮動小数点数ではなく文字列の検証を要求しました。それはなりますあなたが「-1.0」(文字列)を渡す場合、それは意志動作していないあなたが-1.0(フロート)を渡す場合は仕事、それはで開始するための必要条件ではありませんでした。参照してください3v4l.org/bOX6X
ゴードン

20

ドミニクの答えに+1(を使用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してください(その特定のケースは入力文字列をトリミングすることでより明確に処理されるのでしょうか)。
ドミニクロジャー

6
このメソッドは、数値以外の文字列では機能しません。is_int( "abc" +0)はtrue
Kai Pommerenke

1
確かに、それは数値以外の文字列では機能しません...約is_int($inty + 0) && is_numeric($inty)(私はそれが遅延ソリューションであることを知っていますが、ほとんどの意図と目的で機能します...
Alex Mantaut

タイプジャギングを使用すると、intをあらゆる種類の文字列の方法で表すことができるかなり緩いチェックが行われます。これは文字列のチェックではありません。+0にする必要もありません。+ $ varするだけです。
jgmjgm 2017

13

intにキャストします。それでも値が同じ場合は、そのint。

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

2
またはさらに短い:return $var == (int) $var;
Al.G.

1
@ AI.G。キャストが失敗するとどうなるか
DR。

これは非常に近いので、必要でない場合でも型のジャグリングを回避する必要があります。これは、$ varが「123xxxx」の場合に機能します。
jgmjgm 2017

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

私はこれらのハックも好きではありません。しかし、このアプローチまたはDominicによるctypeの提案を使用して、すべての実装をメソッドにカプセル化します。phpを使用するとき、私は常にこれらの問題に対処するための「Util」クラスを持っています。
GmonC 2010年

elseifちょうどすることができifますが、すでに上記のステートメントで返されたので。
rybo111 2015年

最後にfalseを返す必要もありません。
rybo111 2015年

1
場合は$data、オブジェクトがあり、これが返されますnullreturn false;最後に持っている方が良いです。
セオドアR.スミス

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

私が使用したい本当にきれいな方法の1つは、その方法です。最初にint、次にで2回キャストしてから、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]+$/'
DenilsonSáMaia

これはctype_digitと同じですが、末尾の改行も許可します。
jgmjgm 2017

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 2017

1
これがあなたの望むものであることを確認するには、十分に文書化されていないので、PHPソースを読む必要があります。たとえば、is_numericは先頭の空白を受け入れますが、これはPHPマニュアルに記載されているものではありません。また、ネイティブのintで表現するには大きすぎる文字列整数は、浮動小数点に変換されることに注意してください。
jgmjgm 2017

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 2017

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でfalseを返す理由がわかりません。テストしましたか?----- 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 2017

2

多分それを行うための最もパフォーマンスの高い方法ではありません。ただし、1行で記述できます。

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

$ inputが文字列型であることを確認する限り、これは正しいです。
jgmjgm 2017

2

数年遅れましたが、ここで与えられた回答に基づいて、他のほとんどの回答よりも少し正確(特にブール値)で効率的(私は思う)なソリューションを思いつきました。

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

これらを除いて:

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にキャストできる文字列番号に対してのみtrueを返す必要がありますintval()(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')や16進数などでも機能するように調整できます。


これは非常に高価なctype_digitです。
jgmjgm 2017

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.

16進数(0x101010)、8進数(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が浮動小数点にキャストするものに対してもtrueを返します。
jgmjgm 2017

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ユーザーにとって、特に既に回答が受け入れられている質問に対して、回答がはるかに役立つでしょう。参照:良い回答を書くにはどうすればよいですか
デビッドバック

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との間のバイナリセーフな変換が必要な場合は、これが採用するアプローチです。

誰もがそれを望んでいるわけではなく、それはユーザー入力を処理する場合かもしれません。filter_varはそれほど悪くはなく、ほとんどの場合、PHPの初心者にとってはかなり安全です。

長さのチェック、ctype_digit、そしてそれが範囲内にあるかどうかの変換された値のチェックも、ユーザー入力に対してかなり確実です。より複雑なスキームでは、トリムまたは正規表現が必要になる場合があります。

その点でここで多くの回答に伴う問題は、質問が曖昧である一方で、回答が曖昧であってはならないということです。ソリューションを提案する場合は、それが何を期待し、何を期待しないかを正確に説明できる必要があります。それがなければ、回答が質問と一致するか、安全かどうかはわかりません。PHPマニュアルでは、関連する各メソッドのすべての警告について説明しているわけではないため、必ずしも役立つとは限りません。ctype_digitやis_intなどは非常に信頼性が高く、簡単に予測できますが、is_numeric、filter_varおよびjuggling(+ $ var)またはキャスト(intval / floatval)の詳細は十分に文書化されていません。

これはPHPのファッジです。文字列を整数として解釈するための無数のスキーマがあり、矛盾があります。整数文字列を検証する最も厳密な方法は、ユーザーに直接公開されません。


0

あなたは、MySQLから数値IDを扱っている、それが有効な非ゼロであるためには、検証課すことをしようとしている場合はint型またはintが、文字列の形式(でMySQLは常に文字列形式のすべてを返すよう)とされていませんNULL。以下を使用できます。これは、int/string-ints私が見つけたものだけを許可する最もエラー/警告/通知の証明方法です。

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

0

is_numericfloatval、および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より大きい値はfalseを返す場合があることに注意してください。


-1

is_numeric()を使用してから、「。」の存在を確認することもできます。文字列内(ただし、特にカルチャに依存しない)。

または、is_numeric()を使用してからdoubleにキャストし、$ var == floor($ var)かどうかを確認します(整数の場合はtrueを返します)。


これは、ロケールの変更を認識する唯一の答えであり、PHPが数値を解釈して出力する方法も変更します。setlocaleと、セパレーターを想定したソリューションには十分注意してください。
jgmjgm 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.