PHPで数値チェックを行う方法
Contents
前説
金額に関わる(例えば、銀行や不動産)システムにおいて、数値チェックは必ず発生すると思います。前回はPHPで日付チェックを行う方法を紹介しました。続いて、PHPで数値チェックを行う方法を紹介したいと思います。
PHPの数値は整数と浮動小数点数(以下、小数)2種類がありますので、そのため、整数のPHPで数値チェックを行う方法と小数のPHPで数値チェックを行う方法を分けて解説したいと思います。
実際のプロジェクトにおいて、数値チェックは主に下記の三つです。(記憶中にこれくらいしかない、足りなかったらコメントで補足して頂きますと助かります。)
整数のみのチェック X 記号あり/なし X カンマあり/なし
整数、小数混在のチェック X 記号あり/なし X カンマあり/なし
(小数のみのチェックの場合もあると思いますが、混在チェックをベースにし少し直せば対応できるので、ここで解説しません)
また、日付チェックと同じように、PHPで数値チェックを行う方法は主に、整合性チェックと桁数チェック、2つのステップに分けて行います。
※今回紹介したPHPで数値チェックを行う方法はWEB画面から入力した文字列が数値かどうかのチェック方法となり、PHP本家の「is_int」や「is_numeric」関数の使う場面が異なるため、予めご了承ください。
整数のPHPで数値チェックを行う方法
まずは、整数の記号なしチェック方法から解説します。
整数、記号なしの場合
記号なしの場合のチェックは下記のサンプルの通りとても簡単で一行だけ済みます。
1 2 3 4 5 6 7 8 9 |
function isInt($str){ return (bool) preg_match('/^(0|[1-9][0-9]*)$/', $str); } |
整数、記号ありの場合
記号ありの場合、記号なしをベースし、記号を正規表現式に入れるだけで済みます。
1 2 3 4 5 6 7 8 9 |
function isInt($str){ return (bool) preg_match('/^(0|(\+|\-)?[1-9][0-9]*)$/', $str); } |
ここで注意してほしいのは、ゼロは正の数、負の数にも含まれないため、記号なしということです。
カンマ付きの場合
カンマ付きの場合はちょっと複雑です。カンマ付いていない整数も許すことにすれば、尚且つ複雑です。
ここで一旦考え方を整理させていただきます。
まず、チェック要件としては、
1.カンマ付きの数値の文字列は数値として判断する
2.カンマ付いていない数値の文字列も数値として判断する
3.カンマ付いているが、右から3桁ごとに付いていない数値の文字列は数値ではいとして判断する(いわゆる、フォーマットチェック)
4.全角文字と半角スペースを含む数値の文字列は数値ではいとして判断する
のことです。
上記の要件を踏まえて、PHPで数値チェックを行う順番は
1.カンマを抜いて、正規表現で整数かどうかを判断する(要件No.4を満たす、カンマ抜き前提で数値であることを保証する)
2.カンマを含めない文字列は数値として判断する(要件No.2を満たす)
3.カンマ付きですが、カンマの位置が正しいかどうかを判断する(要件No.3を満たす)
4.上記には問題がなければ、数値として判断する(要件No.1を満たす)
のことです。
サンプルです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
function isInt($str){ //カンマを抜いておいて $tmp = str_replace(',','',$str); //1.全角数字やスペースなどをここで一発でブロックし、カンマ抜き状態の整数のみを通す if (!preg_match('/^(0|(\+|\-)?[1-9][0-9]*)$/', $tmp)){ return false; } //2.元々カンマを含めていない整数は当然整数なので(言葉が何かヘン)、ここで優しく許してあげる if(strpos($str,',')===false){ return true; } //3.「10,00」や「,1000」などいたずら入力値を最後にブロックする $tmp = number_format($tmp); if( $tmp !== $str){ return false; } return true; } |
テストパターンも複雑のため、テスト用のサンプルも一緒に提供します。いろいろお試しください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$test = array("0",0,"+0","-0","1000","+1000","-1000","1,000","+1,000","-1,000",",1000","10,00","1000,","1000.10","0.01","1000",""," ","1 ","1 "); foreach ($test as $v){ if (isInt($v)){ echo "「".var_export($v, true) . "」は整数です", PHP_EOL; } else{ echo "「".var_export($v, true) . "」は整数ではないです", PHP_EOL; } } |
小数のPHPで数値チェックを行う方法
小数点のことを考慮しなければならないため、小数のPHPで数値チェックを行う方法は整数より少し複雑ですが、考え方は同じです。
小数記号なしの場合
実際のプロジェクトにおいて、小数チェックに伴い、小数点以下何桁まで許すか、いわゆる、フォーマットチェックを含めて一緒にチェックする要件が多い(ほぼ100%)かと思います。
ですので、フォーマットチェックを含めて下記のようなサンプルを提供します。例えば、整数部が最大8桁、小数部が最大2件の場合、第2引数に「8.2」を設定すれば、良いです。
1 2 3 4 5 6 7 8 9 10 |
function isDecimal($str,$f){ list($il,$dl) = explode(".", $f); return (bool) preg_match('/^([0-9]|([1-9][0-9]{1,'.($il-1).'}))(\.[0-9]{1,'.$dl. '}){0,1}$/', $str); } |
フォーマット「8.2」のテストサンプルです。お試しください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$test = array("0", ".0", "0.", "0.1", "0.10", "010.10", "0..1", "0.1.", "0.123", "12345678.12", "123456789.12", "12345678.123", "+12.12", "-12.12"); foreach ($test as $v){ if (isDecimal($v, "8.2")){ echo "「".var_export($v, true) . "」は小数です", PHP_EOL; } else{ echo "「".var_export($v, true) . "」は小数ではないです", PHP_EOL; } } |
小数記号ありの場合
上記の記号なし正規表現式に記号を追加すれば、完成です。解説が必要なことろは特にないと思います。
1 2 3 4 5 6 7 8 9 10 |
function isDecimal($str,$f){ list($il,$dl) = explode(".", $f); return (bool) preg_match('/^([0-9]|(\+|\-)?([1-9][0-9]{1,'.($il-1).'}))(\.[0-9]{1,'.$dl. '}){0,1}$/', $str); } |
カンマ付きの場合
厄介なカンマ付きチェックですね。基本的に、考え方は整数チェックと同じですが、小数部のカンマのいたずらチェックも考慮しなければならないため、少し手間がかかります。
サンプルです。注意してほしいところを注釈で解説します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
function isDecimal($str,$f){ //カンマを抜いておいて $tmp = str_replace(',','',$str); list($il,$dl) = explode(".", $f); if(!preg_match('/^([0-9]|(\+|\-)?([1-9][0-9]{1,'.($il-1).'}))(\.[0-9]{1,'.$dl. '}){0,1}$/', $tmp)){ return false; } if(strpos($str,',')===false){ return true; } //--------------ここまでは整数チェックと同じ--------------// //--------------カンマのいたずらチェックは基本的に整数チェックと同じですが、小数部も付いているので、それぞれのチェックは必要--------------// //整数部と小数部を分離(小数部がない場合もあるので要注意) list($i,$d) = explode(".", $str); $tmp = number_format(str_replace(',','',$i)); if( $tmp !== $i){ return false; } //小数部のカンマを許さない!! if(strpos($d,',')){ return false; } return true; } |
テスト用のサンプルも一緒に提供します。いろいろお試しください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$test = array("0", ".0", "0.", "0.1", "0.10", "010.10", "0..1", "0.1.", "0.123", "12345678.12", "12345678", "123456789.12", "12345678.123", "+12.12", "-12.12", "1,234.12", "1,234.1,234", ",1234.12"); foreach ($test as $v){ if (isDecimal($v, "8.4")){ echo "「".var_export($v, true) . "」は小数です", PHP_EOL; } else{ echo "「".var_export($v, true) . "」は小数ではないです", PHP_EOL; } } |
まとめ
PHPで数値チェックを行う方法を紹介しました。長かったですね。お疲れ様でした。サンプルが実際のプロジェクトにお役に少しでも立てたのであれば嬉しいです。
こちらも疲れました。それでは、また!!
ディスカッション
コメント一覧
まだ、コメントがありません