PHP Tips | 文字列処理:実務向け便利系 - 文字列中の数値を数値化

PHP PHP
スポンサーリンク

「文字列中の数値を数値化」とは何をしたいのか

業務システムでは、ユーザー入力や CSV から読み込んだ値が「文字列」として渡ってくることが多いです。

"123"
" 1,234 "
"9876"(全角)

見た目は数字なのに、型としては「文字列」なので、そのままでは計算に使えません。
ここでやりたいのが、「“数字っぽい文字列”を、ちゃんとした数値(int / float)に変換する」ことです。

ポイントは、単に (int)$str とキャストするのではなく、

  • 本当に数値として妥当かチェックする
  • カンマや全角数字など、よくある“ノイズ”をうまく吸収する

この 2 つをきちんとやることです。


まずは「素直な数値文字列」を安全に数値化する

filter_var を使った基本形

一番シンプルなケースからいきます。
"123""45.67" のような、余計なものが付いていない文字列です。

PHP には filter_var() という便利な関数があり、
FILTER_VALIDATE_INTFILTER_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;
}
PHP
to_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;
}
PHP
to_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;
}
PHP
to_float_or_null('123.45');   // 123.45
to_float_or_null('12.3.4');   // null
PHP

日本語環境だと、「小数点に , を使う文化圏」との違いもありますが、
日本向けシステムなら「小数点は . 固定」と割り切ってしまうことが多いです。


例題:フォームの金額入力を「数値として」扱う

ユースケースのイメージ

管理画面で「金額」を入力させるフォームがあり、
ユーザーは 1,2341234 のように入力してくる可能性があります。

サーバー側では、「内部では 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_kanastr_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」というルールを徹底するだけで、数値周りのバグはかなり減ります。

タイトルとURLをコピーしました