何をしたいユーティリティなのか
「数値文字列判定」は、 「この文字列、ちゃんと“数値として扱っていいやつ”か?」をチェックするためのユーティリティです。
フォーム入力、クエリパラメータ、JSON の値など、 一見数字っぽいけど、実は変な文字が混ざっていることがあります。
"123" は OK。 " 123 " はどうする? "00123" は? "12.5" は? "123"(全角)は?
ここを自分でルール決めして、コードに落とし込むのが「数値文字列判定」です。
PHP の is_numeric のクセを知る
is_numeric は「ゆるめの判定」
PHP には is_numeric があります。
var_dump(is_numeric('123')); // true
var_dump(is_numeric('12.5')); // true
var_dump(is_numeric('+10')); // true
var_dump(is_numeric('1e3')); // true (指数表記)
var_dump(is_numeric('0123')); // true
var_dump(is_numeric('123')); // true(全角数字も true)
PHP「数値として解釈できるか」を見ているので、 指数表記や全角数字も OK になります。
業務で「ID としての整数だけを許したい」場合には、 このゆるさが逆に困ることがあります。
「整数だけ」を判定するユーティリティ
正規表現で「0〜9 だけ」を許す
「整数だけ」「マイナスも含めるかどうか」など、 ルールをはっきり決めてしまうのが一番分かりやすいです。
例えば、「0〜9 の数字だけ」「先頭に任意でマイナスを許す」というルールなら、こう書けます。
/**
* 「整数として扱ってよい文字列か」を判定する
*
* ルール:
* - 先頭に任意で '-' を許可
* - それ以外は 0〜9 の数字だけ
* - 空文字は false
*/
function is_int_string(string $value): bool
{
// 前後の空白は許さないなら trim しない
// 許したいならここで trim する
if ($value === '') {
return false;
}
return (bool)preg_match('/^-?[0-9]+$/', $value);
}
PHPこの関数の重要ポイントは、「自分でルールを決めている」ことです。
^-?[0-9]+$ という正規表現は、
^… 文字列の先頭-?… マイナス記号が 0 回または 1 回[0-9]+… 数字が 1 回以上$… 文字列の末尾
という意味になります。
例題で挙動を確認する
OK になるもの
var_dump(is_int_string('0')); // true
var_dump(is_int_string('123')); // true
var_dump(is_int_string('-10')); // true
PHP「純粋な整数」として扱いたいものは、ちゃんと true になります。
NG にしたいもの
var_dump(is_int_string('')); // false
var_dump(is_int_string(' 123')); // false(先頭に空白)
var_dump(is_int_string('12.5')); // false(小数点)
var_dump(is_int_string('+10')); // false(プラス記号)
var_dump(is_int_string('1e3')); // false(指数表記)
var_dump(is_int_string('123')); // false(全角数字)
PHP「ID としてはおかしいよね」というものは、全部 false になります。 ここが is_numeric との大きな違いです。
「前後の空白は許す」版も作っておく
trim を入れるかどうかは設計の話
ユーザー入力だと、うっかり前後に空白が入ることがあります。
" 123 "
これを「許すかどうか」は設計次第ですが、 許したいなら trim を入れた別関数を用意しておくと分かりやすいです。
function is_int_string_trimmed(string $value): bool
{
$value = trim($value);
if ($value === '') {
return false;
}
return (bool)preg_match('/^-?[0-9]+$/', $value);
}
PHPこうしておけば、
- DB の ID チェックには「trim なし版」
- フォーム入力のチェックには「trim あり版」
といった使い分けができます。
「数値として扱えるか」をざっくり見たいときのユーティリティ
is_numeric をラップしておく
「整数だけじゃなく、小数も指数表記も許したい。とにかく数値なら OK」という場面もあります。 その場合は、is_numeric をそのまま使いつつ、前後の空白だけ整えておくと扱いやすいです。
/**
* 「数値として解釈できる文字列か」を判定する(ゆるめ)
*
* - 前後の空白は無視
* - is_numeric にそのまま渡す
*/
function is_numeric_string(string $value): bool
{
$value = trim($value);
if ($value === '') {
return false;
}
return is_numeric($value);
}
PHP例:
var_dump(is_numeric_string('12.5')); // true
var_dump(is_numeric_string('1e3')); // true
var_dump(is_numeric_string(' 10 ')); // true
var_dump(is_numeric_string('abc')); // false
PHP「型安全な整数判定」とは別に、「ざっくり数値かどうか」を見るユーティリティもあると便利です。
実務での使いどころ
ID や数量のバリデーション
フォームで「ユーザー ID」「数量」「ページ番号」などを受け取るとき、 is_int_string でチェックしてから intval する、という流れが定番になります。
$rawId = $_GET['id'] ?? '';
if (!is_int_string($rawId)) {
// 不正な ID として扱う
throw new InvalidArgumentException('id must be integer string');
}
$id = (int)$rawId;
PHP「文字列のままだけど、整数として扱っていいか」を先に判定しておくことで、 変な値が入り込むのを防げます。
JSON や設定ファイルの値チェック
JSON や設定ファイルから読み込んだ値が「本当に数値か」を確認したいときも同じです。
$config = decode_json_to_array($json);
if (!array_key_exists('max_users', $config) || !is_int_string((string)$config['max_users'])) {
throw new RuntimeException('config.max_users must be integer string');
}
$maxUsers = (int)$config['max_users'];
PHP「型のズレ」を早めに検知しておくことで、 後の処理でのバグを減らせます。
まとめ:今日からの「数値文字列判定」ユーティリティ
数値文字列判定の本質は、「自分が“数値として扱いたいルール”をコードに落とす」ことです。
整数だけを許したいなら、preg_match('/^-?[0-9]+$/') のような正規表現で厳しく見る。 前後の空白を許すかどうかは、trim を入れるかどうかで分ける。 小数や指数表記も含めてざっくり数値を許したいなら、is_numeric をラップする。
まずは、この 1 本をプロジェクトに置いておくと良いです。
function is_int_string(string $value): bool
{
if ($value === '') {
return false;
}
return (bool)preg_match('/^-?[0-9]+$/', $value);
}
PHPそして、「ここは ID だから絶対整数」「ここは数量だから整数」「ここは金額だから小数もあり」 といったルールごとに、どの判定関数を使うかを決めていく。 それだけで、入力まわりの「変な値」に悩まされることが、かなり減ります。
