「文字列中の数値を数値化」とは何をしたいのか
業務システムでは、ユーザー入力や CSV から読み込んだ値が「文字列」として渡ってくることが多いです。
"123"" 1,234 ""9876"(全角)
見た目は数字なのに、型としては「文字列」なので、そのままでは計算に使えません。
ここでやりたいのが、「“数字っぽい文字列”を、ちゃんとした数値(int / float)に変換する」ことです。
ポイントは、単に (int)$str とキャストするのではなく、
- 本当に数値として妥当かチェックする
- カンマや全角数字など、よくある“ノイズ”をうまく吸収する
この 2 つをきちんとやることです。
まずは「素直な数値文字列」を安全に数値化する
filter_var を使った基本形
一番シンプルなケースからいきます。"123" や "45.67" のような、余計なものが付いていない文字列です。
PHP には filter_var() という便利な関数があり、FILTER_VALIDATE_INT や FILTER_VALIDATE_FLOAT を使うと「妥当な数値かどうか」を判定できます。
/**
* 素直な整数文字列を int に変換(不正なら null)
*/
function to_int_or_null(string $value): ?int
{
$value = trim($value);
if ($value === '') {
return null;
}
$result = filter_var($value, FILTER_VALIDATE_INT);
return $result === false ? null : $result;
}
PHP使い方の例です。
to_int_or_null('123'); // 123
to_int_or_null(' 45 '); // 45
to_int_or_null('12a'); // null
to_int_or_null(''); // null
PHPここでの重要ポイントは、「不正な値は 0 ではなく null にする」ことです。(int)'abc' は 0 になりますが、それは「0 という値」ではなく「変換失敗」です。null を返すことで、「変換できなかった」という状態をはっきり区別できます。
実務でよくある「カンマ付き」「全角数字」を扱う
カンマを取り除いてから検証する
金額入力でよくあるのが、"1,234" のようなカンマ付きの文字列です。
そのままでは FILTER_VALIDATE_INT に通らないので、先にカンマを削除します。
/**
* カンマ付き整数文字列を int に変換(不正なら null)
*/
function to_int_from_human(string $value): ?int
{
$value = trim($value);
if ($value === '') {
return null;
}
// カンマを除去
$value = str_replace(',', '', $value);
$result = filter_var($value, FILTER_VALIDATE_INT);
return $result === false ? null : $result;
}
PHPto_int_from_human('1,234'); // 1234
to_int_from_human('12,34'); // 1234(※カンマ位置の妥当性まで見るなら追加チェックが必要)
to_int_from_human('1,2,3'); // 123
PHPカンマの位置まで厳密にチェックしたい場合は、/^-?\d{1,3}(,\d{3})*$/ のような正規表現で「3 桁区切りかどうか」を先に判定する、という一段階を足せます。
全角数字を半角にしてから処理する
日本語環境では、"1234" のような全角数字もよく出てきます。
これは mb_convert_kana() で半角に変換してから、さきほどの処理に流せます。
/**
* 全角数字・カンマ付きも許容して int に変換(不正なら null)
*/
function to_int_from_jp_human(string $value): ?int
{
$value = trim($value);
if ($value === '') {
return null;
}
// 全角数字を半角に
$value = mb_convert_kana($value, 'n', 'UTF-8');
// カンマを除去
$value = str_replace(',', '', $value);
$result = filter_var($value, FILTER_VALIDATE_INT);
return $result === false ? null : $result;
}
PHPto_int_from_jp_human('1234'); // 1234
to_int_from_jp_human('1,234'); // 1234
PHPここでの重要ポイントは、「見た目が違っても、意味としては同じ“数値”を受け入れる」ことです。
ユーザー入力を扱うときは、こうした“人間寄りの表記”を吸収してあげると、使い勝手がかなり良くなります。
小数(float)を扱う場合の考え方
filter_var(FILTER_VALIDATE_FLOAT) の利用
小数を扱いたい場合は、FILTER_VALIDATE_FLOAT を使います。
/**
* 小数文字列を float に変換(不正なら null)
*/
function to_float_or_null(string $value): ?float
{
$value = trim($value);
if ($value === '') {
return null;
}
$result = filter_var($value, FILTER_VALIDATE_FLOAT);
return $result === false ? null : $result;
}
PHPto_float_or_null('123.45'); // 123.45
to_float_or_null('12.3.4'); // null
PHP日本語環境だと、「小数点に , を使う文化圏」との違いもありますが、
日本向けシステムなら「小数点は . 固定」と割り切ってしまうことが多いです。
例題:フォームの金額入力を「数値として」扱う
ユースケースのイメージ
管理画面で「金額」を入力させるフォームがあり、
ユーザーは 1,234 や 1234 のように入力してくる可能性があります。
サーバー側では、「内部では int(1234)として扱いたい」というケースです。
実装例
$rawAmount = $_POST['amount'] ?? '';
$amount = to_int_from_jp_human($rawAmount);
if ($amount === null || $amount < 0) {
$error = '金額の入力が不正です。';
} else {
// $amount は「整数の金額」として安全に使える
}
PHPここでの重要ポイントは、
- 「文字列 → 数値化」の責務をユーティリティ関数に閉じ込める
- 呼び出し側は「null かどうか」「範囲チェック」に集中できる
という分離です。
これをやっておくと、同じ変換ロジックをあちこちにコピペせずに済みます。
まとめ:今日からの「文字列中の数値を数値化」ユーティリティ
本質は、「“数字っぽい文字列”を、ちゃんと検証したうえで int / float に変換し、不正なものは null にする」ことです。
素直な数値 → filter_var(..., FILTER_VALIDATE_INT/FLOAT)。
人間向け表記(カンマ・全角) → 前処理(mb_convert_kana・str_replace)してから同じ検証。
まずは、こんな 1 本をプロジェクトに置いておくと便利です。
function to_int_from_jp_human(string $value): ?int
{
$value = trim($value);
if ($value === '') {
return null;
}
$value = mb_convert_kana($value, 'n', 'UTF-8');
$value = str_replace(',', '', $value);
$result = filter_var($value, FILTER_VALIDATE_INT);
return $result === false ? null : $result;
}
PHPもし、あなたのコードのどこかで「(int)$_POST['amount'] のように、いきなりキャストしている」箇所があれば、そこがこのユーティリティに差し替えるべきポイントです。
「変換できないものは 0 ではなく null」というルールを徹底するだけで、数値周りのバグはかなり減ります。
