42

これは私にとって大きな問題ではありません(私が知る限り)、それは私が興味を持っていることです。is_numericしかし、ユーザー入力値を検証するためにover preg_match(またはその逆)を使用することの主な違いは何ですか(またはその逆)。

例1:

<?php
    $id = $_GET['id'];
    if (!preg_match('/^[0-9]*$/', $id)) {
        // Error
    } else {
        // Continue
    }
?>

例2:

<?php
    $id = $_GET['id'];
    if (!is_numeric($id)) {
        // Error
    } else {
        // Continue
    }
?>

どちらもまったく同じだと思いますが、後で問題を引き起こす可能性のある特定の違いはありますか?それらを違うものにする「最良の方法」または私が見ていなかった何かがありますか?

4

12 に答える 12

68

is_numeric()値が数値であるかどうかをテストします。ただし、必ずしも整数である必要はありません。10進数または科学的記数法の数値である可能性があります。

与えたpreg_match()例では、値に0から9までの数字が含まれていることだけをチェックしています。それらの任意の数、および任意の順序で。

あなたが与えた正規表現もまた、あなたがそれを書いた方法である完全な整数チェッカーではないことに注意してください。ネガは許可されません。長さゼロの文字列(つまり、数字がまったくない、おそらく有効ではないはずですか?)を許可し、数値に先行ゼロをいくつでも含めることができますが、これも意図されていない可能性があります。

[編集]

あなたのコメントによると、より良い正規表現は次のようになります。

/^[1-9][0-9]*$/

これにより、最初の桁が1から9の間になるように強制されるため、先行ゼロを設定することはできません。また、少なくとも1桁の長さにする必要があるため、長さがゼロの文字列の問題を解決します。

あなたはネガティブについて心配していないので、それは問題ではありません。

現状では、大きすぎる文字列を整数として格納できないため、桁数を制限することをお勧めします。これを制限するには、星を次のような長さ制限に変更します。

/^[1-9][0-9]{0,15}$/

これにより、文字列の長さは1〜16桁になります(つまり、最初の桁に0〜15桁を加えたもの)。中括弧内の数字は、自分のニーズに合わせて自由に調整してください。固定長の文字列が必要な場合は、中かっこで1つの数字を指定するだけで済みます。

お役に立てば幸いです。

于 2011-10-04T14:54:40.310 に答える
12

http://www.php.net/manual/en/function.is-numeric.phpによると、is_numericは「+0123.45e6」や「0xFF」のようなものです。これはあなたが期待することではないと思います。

preg_matchは遅くなる可能性があり、0000や0051のようなものを持つことができます。

私はctype_digitを使用することを好みます(文字列でのみ機能し、$ _ GETでも問題ありません)。

<?php
  $id = $_GET['id'];
  if (ctype_digit($id)) {
      echo 'ok';
  } else {
      echo 'nok';
  }
?>
于 2011-10-04T14:57:50.323 に答える
7

is_numeric()は、任意の形式の数値を許可します。したがって1、、、はすべて「数値」ですが、正規表現は次のようになります3.141592652.71828e10is_int()

于 2011-10-04T14:51:56.840 に答える
5

is_numericは、有効なIDとして「-0.5e+12」を受け入れます。

于 2011-10-04T14:51:07.950 に答える
5

まったく同じではありません。

is_numericのPHPドキュメントから:

'42' is numeric
'1337' is numeric
'1e4' is numeric
'not numeric' is NOT numeric
'Array' is NOT numeric
'9.1' is numeric

正規表現では、「基本的な」数値のみをチェックします。

またis_numeric()、より高速である必要があります。

于 2011-10-04T14:51:33.760 に答える
5

is_numericはそれが何らかの数値であるかどうかをチェックし、正規表現はそれが整数であるかどうかをチェックします。整数として格納されているIDの場合、先頭に0を付けたくない可能性が非常に高くなります。Spudleyの回答に従って、次のことができます。

/^[1-9][0-9]*$/

ただし、Spudleyが指摘しているように、結果の文字列は大きすぎて32ビットまたは64ビットの整数値として格納できない場合があります。符号付き32ビット整数の最大値は2,147,483,647(10桁)であり、符号付き64ビット整数の最大値は9,223,372,036,854,775,807(19桁)です。ただし、多くの10桁および19桁の整数は、それぞれ最大32ビットおよび64ビット整数よりも大きくなります。単純な正規表現のみのソリューションは次のようになります。

/^[1-9][0-9]{0-8}$/ 

また

/^[1-9][0-9]{0-17}$/

それぞれ、しかしこれらの「解決策」は不幸にもそれぞれを9桁と19桁の整数に制限します。満足のいく結果はほとんどありません。より良い解決策は次のようなものかもしれません:

$expr = '/^[1-9][0-9]*$/';
if (preg_match($expr, $id) && filter_var($id, FILTER_VALIDATE_INT)) {
    echo 'ok';
} else {
    echo 'nok';
}
于 2013-10-30T05:21:56.077 に答える
3

is_numeric詳細をチェックします:

指定された変数が数値であるかどうかを検索します。数値文字列は、オプションの符号、任意の桁数、オプションの小数部分、およびオプションの指数部分で構成されます。したがって、+0123.45e6は有効な数値です。16進表記(0xFF)も許可されますが、符号、小数、および指数部分は使用できません。

于 2011-10-04T14:52:00.663 に答える
2

このコードを番号の検証に使用できます。

if (!preg_match("/^[0-9]+$/i", $phone)) {
        $errorMSG = 'Invalid Number!';
        $error    = 1;
    }
于 2017-11-14T12:42:03.237 に答える
1

数字かどうかだけをチェックしている場合は、ここの方is_numeric()がはるか優れています。正規表現よりも読みやすく、少し高速です。

ここでの正規表現の問題は、10進値が許可されないことです。したがって、基本的にis_int()は正規表現で記述しただけです。正規表現は、入力に非標準のデータ形式がある場合にのみ使用する必要があります。PHPには、正規表現のない電子メールバリデーターでさえ、多くの検証関数が組み込まれています。

于 2011-10-04T14:51:05.227 に答える
1

PHPのis_numeric関数では、整数だけでなく浮動小数点数も使用できます。同時に、フォームデータ(文字列のみ)を検証する場合、is_int関数は厳密すぎます。したがって、通常、これには正規表現を使用するのが最適です。

厳密に言えば、整数は正と負の整数であり、ゼロも含まれます。これの正規表現は次のとおりです。

/ ^ 0 $ | ^ [-]?[1-9] [0-9] * $ /

または、先行ゼロを許可する場合:

/ ^ [-]?[0] | [1-9] [0-9] $ /

ただし、これにより-0000などの値が許可されるため、PHPで問題が発生することはありません。(MySQLは0などの値もキャストします。)

32/64ビットPHPプラットフォームの機能やデータベースの互換性を考慮して、整数の長さを制限することもできます。たとえば、整数の長さを9桁に制限するには(オプションの-記号を除く)、次を使用できます。

/ ^ 0 $ | ^ [-]?[1-9] [0-9] {0,8} $ /

于 2014-06-09T14:51:21.530 に答える
0

一方、上記のすべての値は値を整数に制限するだけなので、私は

/^[1-9][0-9\.]{0,15}$/

float値も許可します。

于 2015-03-24T08:47:44.470 に答える
0

filter_var()を使用して、文字列内の整数をチェックできます

<?php
$intnum = "1000022";
if (filter_var($intnum, FILTER_VALIDATE_INT) !== false){
    echo $intnum.' is an int now';
}else{
    echo "$intnum is not an int.";
}
// will output 1000022 is an int now
于 2021-12-16T18:12:16.713 に答える