web-dev-qa-db-ja.com

PHP is_numericまたはpreg_match 0-9検証

これは私にとって大きな問題ではありません(私が知っている限り)、それは私にとって興味のあることです。ただし、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
    }
?>

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

35
no.

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つの数値のみを指定する必要があります。

お役に立てば幸いです。

61
Spudley

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';
  }
?>
11
rap-2-h

is_numeric()は、あらゆる形式の数値を許可します。 _1_、_3.14159265_、_2.71828e10_はすべて「数値」ですが、正規表現はis_int()と同等のものになります

7
Marc B

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

5
user187291

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

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

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

正規表現では、「基本」数値のみを確認します。

また、is_numeric()はより高速になるはずです。

5
PeeHaa

is_numericは、それが数字の種類であるかどうかをチェックします。一方、正規表現は、整数であるかどうか、場合によっては先頭に0が付いているかどうかをチェックします。整数として保存された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';
}
5
Jacob Lee

is_numericはさらにチェックします。

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

3
MasterCassim

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

if (!preg_match("/^[0-9]+$/i", $phone)) {
        $errorMSG = 'Invalid Number!';
        $error    = 1;
    }
1
vicky mahale

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

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

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

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

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

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

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

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

1
mixabo

あなたがonlyそれが数字であるかどうかをチェックしている場合、is_numeric()はずっとmuchここで改善されました。正規表現よりも読みやすく、少し高速です。

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

1
Bojangles

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

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

フロート値も許可します。

0
tormuto