web-dev-qa-db-ja.com

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

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

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

例えば。:

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

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 と組み合わせます。

負の数を気にする場合は、先行する-の入力を確認する必要があります。その場合は、入力文字列の substrctype_digitを呼び出します。このような何かがそれを行うだろう:

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

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);
}
79
Gordon

Dominicの回答に+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
18
nickf

Intにキャストします。まだ同じ値を持っている場合、int;

function my_is_int($var) {
  $tmp = (int) $var;
  if($tmp == $var)
       return true;
  else
       return false;
}
12
greg
/**
 * 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);
    }
}

ソース

7
GmonC

最近、堅牢な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ドキュメンテーションコメントでこのスニペットに出会って、テスト後、almostスローするすべてをカバーします:

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
Costa
function my_is_int($var) {
    return preg_match('/^\d+$/', $var);
}
4
Michael Connor

私が使用したい本当にきれいな方法の1つは、その方法です。最初にintで、次にstringで2回キャストし、次に===を厳密に比較します。以下の例を参照してください。

$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
Jonathan Gagne

数字を確認するだけで、それがキャストの場合は倍精度が与えられているかどうかを確認できます:

((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)
3
Jordi Martínez

私はこれを使用しています:

function isInt($val){

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

}

var_dump (isInt("1"));
3
julesdude
function my_is_int($var){
    return is_numeric($var) && gettype($var+0)=='integer';
}
2
grant sun

これを試して:

$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に小数点以下の桁がある場合にも機能します

2
Jack M.

これも負の数を処理します

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

たぶんそれを行う最もパフォーマンスの良い方法ではありません。ただし、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
2
mwallisch

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

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
2
SharkWipf
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;
}
1
Volker

どこにも見つからない方法を考案したので、ここに入れています:

さらに苦労せずにこれは次のとおりです: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
Smuuf

どうですか:

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)またはintval()を使用してintにキャストできる任意の文字列番号に対してのみ、数学的に意味のあるもの(小数点以下の非ゼロまたはPHPの整数範囲外の数値など) )数学的に重要ではないもの(空白、先行ゼロ、または小数点以下ゼロのみなど)を受け入れます。

'10.'に対してはfalseを返しますが、'10.0'に対しては返しません。 '10.'をtrueにしたい場合は、正規表現の+の後の0*に変更できます。

1
user2923827

次の条件を使用できます。 !==を使用しないでください。

$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
Saman Shafigh

ここで私が使用したいくつかのコードはうまく機能しているようで、他の多くのコードが抱えている問題はありません。

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

順序などはチェックしないため、負の整数用ではありませんが、上記の他のアイデアのいくつかを使用して同様に実行できる追加コードがあります。また、バイナリarray('0', '1')または16進数などでも動作するように適合させることができます。

1
Dragonaire

こちらをご覧ください。 $ 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
Joe

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を返すことに注意してください。

0
Pikamander2

Mysqlからの数値IDを処理していて、有効な非ゼロintまたはintであるが文字列形式(-mysqlは常にNULLではなく、すべてを文字列形式)で返します。以下を使用できます。これは、私が見つけたint/string-intsのみを許可する、最もエラー/警告/通知を防止する方法です。

...
if(empty($id) || !is_scalar($id) || !ctype_digit($id)){
  throw("Invalid ID");
}
...
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 doesは、文字列が本当に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
jgmjgm