PHPのis_numeric関数について

採用はこちら

PHPのis_numeric()は、値が数値または数値として扱える文字列かどうかを判定する関数です。

フォーム入力やCSVデータ、外部APIから取得した値などは、見た目は数値でも文字列として渡されることがあります。

そのような値を計算に使う前に、「この値は数値として扱ってよいか」を確認したいときにis_numeric()を使います。

is_numeric(mixed $value): bool

戻り値は、数値として扱える場合はtrue、そうでない場合はfalseです。

目次

is_numeric()の基本的な使い方

$value = "123";

if (is_numeric($value)) {
    echo "数値です";
} else {
    echo "数値ではありません";
}

この例では、$valueは文字列の"123"ですが、数値として解釈できるためis_numeric()trueを返します。

var_dump(is_numeric(123));      // true
var_dump(is_numeric("123"));    // true
var_dump(is_numeric("12.3"));   // true
var_dump(is_numeric("abc"));    // false

is_numeric()のポイントは、実際の型が数値かどうかだけを見る関数ではないという点です。

たとえば、"123"は文字列ですが、PHPでは数値文字列として扱えるためtrueになります。

trueになる主な値

is_numeric()では、整数・小数・符号付き数値・指数表記などがtrueになります。

var_dump(is_numeric(100));        // true
var_dump(is_numeric(3.14));       // true
var_dump(is_numeric("100"));      // true
var_dump(is_numeric("3.14"));     // true
var_dump(is_numeric("-100"));     // true
var_dump(is_numeric("+100"));     // true
var_dump(is_numeric("1e3"));      // true
var_dump(is_numeric("0"));        // true

"1e3"は指数表記です。

数値としては1000を意味するため、is_numeric()ではtrueになります。

var_dump((float) "1e3"); // float(1000)

falseになる主な値

一方で、文字が混ざっている値や空文字、配列、nullなどはfalseになります。

var_dump(is_numeric("abc"));      // false
var_dump(is_numeric("123abc"));   // false
var_dump(is_numeric("12px"));     // false
var_dump(is_numeric(""));         // false
var_dump(is_numeric(" "));        // false
var_dump(is_numeric(null));       // false
var_dump(is_numeric(true));       // false
var_dump(is_numeric(false));      // false
var_dump(is_numeric([]));         // false

たとえば、CSSの値のような"12px"は、数値が含まれていても全体としては数値文字列ではありません。

そのため、is_numeric("12px")falseになります。

判定結果の一覧

結果理由
123true整数
12.5true小数
"123"true数値文字列
"0123"true数値文字列
"-123"true符号付き数値
"+123"true符号付き数値
"1e5"true指数表記
"0"true数値文字列
""false空文字
" "false空白のみ
"abc"false数値ではない
"123abc"false文字が混ざっている
"10px"false単位付き文字列
nullfalse数値ではない
truefalsebooleanは対象外
[]false配列は対象外

PHP 8.0以降では末尾の空白も許可される

PHP 8.0以降では、前後に空白がある数値文字列もtrueになります。

var_dump(is_numeric("42"));    // true
var_dump(is_numeric(" 42"));   // true
var_dump(is_numeric("42 "));   // true PHP 8.0以降
var_dump(is_numeric(" 42 "));  // true PHP 8.0以降

ただし、空白だけの文字列は数値ではありません。

var_dump(is_numeric(" ")); // false

ユーザー入力を扱う場合は、先にtrim()で前後の空白を取り除いておくと安全です。

$value = trim($_POST['amount'] ?? '');

if ($value !== '' && is_numeric($value)) {
    echo "数値です";
}

is_numeric()は整数だけを判定する関数ではない

is_numeric()は、整数だけでなく小数や指数表記もtrueにします。

var_dump(is_numeric("10"));     // true
var_dump(is_numeric("10.5"));   // true
var_dump(is_numeric("1e3"));    // true

そのため、年齢や数量のように整数だけを許可したい場合には、is_numeric()だけでは不十分です。

たとえば、次の値はすべてis_numeric()trueになります。

var_dump(is_numeric("20"));    // true
var_dump(is_numeric("20.5"));  // true
var_dump(is_numeric("2e1"));   // true

しかし、年齢入力で"20.5""2e1"を許可したくない場合もあります。

そのような場合は、filter_var()や正規表現を使って、入力ルールを明確にする必要があります。

整数だけを許可したい場合

整数だけを許可したい場合は、正規表現を使う方法があります。

マイナスも許可する整数

$value = "-123";

if (preg_match('/^-?\d+$/', $value)) {
    echo "整数です";
}

この正規表現では、次のような値を許可します。

123
-123
0

0以上の整数

$value = "123";

if (preg_match('/^\d+$/', $value)) {
    echo "0以上の整数です";
}

1以上の整数

数量など、1以上の整数だけを許可したい場合は次のようにします。

$quantity = "5";

if (preg_match('/^[1-9]\d*$/', $quantity)) {
    echo "1以上の整数です";
}

この場合、0-11.5は許可されません。

filter_var()で整数を検証する方法

整数の検証には、filter_var()を使う方法もあります。

$value = "123";

if (filter_var($value, FILTER_VALIDATE_INT) !== false) {
    echo "整数です";
}

ここで重要なのは、比較に!== falseを使うことです。

$value = "0";

if (filter_var($value, FILTER_VALIDATE_INT) !== false) {
    echo "整数です";
}

filter_var("0", FILTER_VALIDATE_INT)0を返します。

0はPHPの条件式ではfalseとして扱われるため、次のような書き方は避けましょう。

if (filter_var($value, FILTER_VALIDATE_INT)) {
    echo "整数です";
}

この書き方だと、"0"が正しい整数であるにもかかわらず、条件を通過しません。

小数を含む通常の数値だけを許可したい場合

is_numeric()"1e3"のような指数表記も許可します。

しかし、価格や金額の入力欄では、指数表記を許可したくない場合もあります。

そのような場合は、正規表現で通常の数値形式だけを許可するとよいでしょう。

$value = "1000.50";

if (preg_match('/^\d+(\.\d+)?$/', $value)) {
    echo "通常の数値形式です";
}

この例では、次のような値を許可します。

100
100.5
0.5

マイナスも許可する場合は、次のようにします。

$value = "-1000.50";

if (preg_match('/^-?\d+(\.\d+)?$/', $value)) {
    echo "通常の数値形式です";
}

ただし、この正規表現では.5100.+100などは許可されません。

どの形式を許可するかは、入力フォームの仕様に合わせて調整しましょう。

empty()と組み合わせるときの注意点

PHPでは、文字列の"0"empty()trueになります。

var_dump(empty("0")); // true

そのため、次のようなコードを書くと、"0"が入力された場合に意図しない判定になります。

$value = "0";

if (!empty($value) && is_numeric($value)) {
    echo "OK";
} else {
    echo "NG";
}

このコードでは、"0"は数値として正しい値ですが、empty("0")trueになるため、結果はNGになります。

0を有効な入力値として扱う場合は、empty()ではなく、空文字かどうかを明示的に確認するのがおすすめです。

$value = "0";

if ($value !== '' && is_numeric($value)) {
    echo "OK";
}

フォーム入力では、trim()と組み合わせるとより実用的です。

$value = trim($_POST['amount'] ?? '');

if ($value === '') {
    echo "値を入力してください";
    exit;
}

if (!is_numeric($value)) {
    echo "数値で入力してください";
    exit;
}

echo "OK";

is_numeric()is_int()is_float()の違い

is_numeric()と似た関数に、is_int()is_float()があります。

これらは似ているようで、判定する内容が異なります。

is_numeric()

数値、または数値として扱える文字列かどうかを判定します。

var_dump(is_numeric(123));     // true
var_dump(is_numeric("123"));   // true
var_dump(is_numeric("12.3"));  // true

is_int()

値の型が整数型かどうかを判定します。

var_dump(is_int(123));    // true
var_dump(is_int("123"));  // false

"123"は数値として扱える文字列ですが、型はstringなのでis_int()ではfalseです。

is_float()

値の型が浮動小数点数型かどうかを判定します。

var_dump(is_float(12.3));    // true
var_dump(is_float("12.3"));  // false

"12.3"は数値文字列ですが、型はstringなのでis_float()ではfalseです。

ctype_digit()との違い

ctype_digit()は、文字列が0〜9の数字だけで構成されているかを判定する関数です。

var_dump(ctype_digit("123"));   // true
var_dump(ctype_digit("12.3"));  // false
var_dump(ctype_digit("-123"));  // false
var_dump(ctype_digit("abc"));   // false

ctype_digit()は、小数点やマイナス記号を許可しません。

そのため、「数字だけの文字列」を判定したい場合に向いています。

ただし、ctype_digit()は基本的に文字列を対象にする関数です。

整数などを判定したい場合は、明示的に文字列へ変換して使うと安全です。

$value = 123;

var_dump(ctype_digit((string) $value)); // true

関数ごとの違い

関数判定内容
is_numeric()数値、または数値として扱える文字列か
is_int()整数型か
is_float()浮動小数点数型か
ctype_digit()文字列が数字だけで構成されているか
filter_var(..., FILTER_VALIDATE_INT)整数として妥当か

比較すると、次のようになります。

is_numeric()is_int()is_float()ctype_digit()
123truetruefalse注意
"123"truefalsefalsetrue
"12.3"truefalsefalsefalse
"-123"truefalsefalsefalse
"1e3"truefalsefalsefalse
"abc"falsefalsefalsefalse

ctype_digit()は文字列を対象に使うのが基本です。

数値型の値をそのまま渡すのではなく、必要に応じて(string)で変換しましょう。

カンマ区切りの数値はfalseになる

ユーザー入力では、金額として"1,000"のようにカンマ付きで入力されることがあります。

しかし、is_numeric()ではカンマ区切りの数値はfalseになります。

var_dump(is_numeric("1000"));   // true
var_dump(is_numeric("1,000"));  // false

カンマ付きの入力を許可する場合は、事前にカンマを除去してから判定する方法があります。

$value = "1,000";
$value = str_replace(',', '', $value);

if (is_numeric($value)) {
    echo "数値です";
}

ただし、単純にカンマを削除すると、"1,2,3"のような不自然な形式も通ってしまう可能性があります。

厳密にチェックしたい場合は、カンマの位置も含めて正規表現で検証するのがおすすめです。

全角数字はそのままだとfalseになる

日本語サイトでは、ユーザーが全角数字を入力することがあります。

var_dump(is_numeric("123")); // false

is_numeric()では、全角数字は通常の数値文字列として扱われません。

全角数字を許可したい場合は、事前に半角数字へ変換します。

$value = "123";
$value = mb_convert_kana($value, 'n', 'UTF-8');

if (is_numeric($value)) {
    echo "数値です";
}

日本語の入力フォームでは、全角数字を半角に変換してからバリデーションする設計にすると、ユーザーにとって使いやすくなります。

郵便番号や電話番号にis_numeric()を使うべきではない

郵便番号や電話番号は、数字で構成されていますが、数値として計算するものではありません。

たとえば、次のような郵便番号があります。

$postcode = "0123456";

これを数値として扱うと、先頭の0が消えてしまう可能性があります。

var_dump((int) "0123456"); // int(123456)

郵便番号や電話番号、会員番号、商品コードなどは、数値ではなく文字列の識別情報として扱うべきです。

そのため、is_numeric()ではなく、桁数や形式を正規表現でチェックするのが適しています。

$postcode = "0123456";

if (preg_match('/^\d{7}$/', $postcode)) {
    echo "郵便番号として有効です";
}

電話番号の場合も、ハイフンの有無など仕様に合わせて正規表現を作るとよいでしょう。

Webフォームでの実用例

数値なら許可する場合

$amount = trim($_POST['amount'] ?? '');

if ($amount === '') {
    echo "金額を入力してください";
    exit;
}

if (!is_numeric($amount)) {
    echo "金額は数値で入力してください";
    exit;
}

$amount = (float) $amount;

echo "入力された金額は {$amount} です";

この例では、整数・小数・指数表記を含め、PHPが数値として解釈できる値を許可します。

0以上の数値だけを許可する場合

$amount = trim($_POST['amount'] ?? '');

if ($amount === '') {
    echo "金額を入力してください";
    exit;
}

if (!is_numeric($amount)) {
    echo "金額は数値で入力してください";
    exit;
}

$amount = (float) $amount;

if ($amount < 0) {
    echo "金額は0以上で入力してください";
    exit;
}

echo "OK";

このように、is_numeric()で数値かどうかを確認したあと、範囲チェックを追加すると実務的です。

数量として1以上の整数だけを許可する場合

$quantity = trim($_POST['quantity'] ?? '');

if ($quantity === '') {
    echo "数量を入力してください";
    exit;
}

if (!preg_match('/^[1-9]\d*$/', $quantity)) {
    echo "数量は1以上の整数で入力してください";
    exit;
}

$quantity = (int) $quantity;

echo "OK";

数量のように、小数や指数表記を許可したくない場合は、is_numeric()よりも正規表現の方が適しています。

is_numeric()を使うのに向いているケース

is_numeric()は、次のような場面に向いています。

ケース理由
文字列が数値として計算できるか確認したい数値文字列を判定できるため
CSVの数値データを処理したいCSVでは数値が文字列として読み込まれることが多いため
APIレスポンスの値を数値変換したい外部データの事前チェックに使えるため
整数・小数・指数表記をまとめて許可したいis_numeric()で一括判定できるため

例:

$value = $row['price'];

if (is_numeric($value)) {
    $price = (float) $value;
}

is_numeric()だけでは不十分なケース

次のような場合は、is_numeric()だけではなく、別の方法で検証した方が安全です。

検証したい値is_numeric()だけでは不十分な理由おすすめ
年齢小数や指数表記も通るfilter_var()または正規表現
数量1.51e3も通る正規表現
金額カンマや全角数字への対応が必要な場合がある事前変換+正規表現
郵便番号先頭ゼロが意味を持つ正規表現
電話番号ハイフンや先頭ゼロを扱う必要がある正規表現
会員番号・商品コード数値ではなく識別子として扱うべき文字列として検証

よくあるミス

ミス1:整数チェックにis_numeric()だけを使う

if (is_numeric($age)) {
    echo "有効な年齢です";
}

このコードでは、"20.5""2e1"も通ってしまいます。

年齢を整数に限定したい場合は、次のようにします。

if (filter_var($age, FILTER_VALIDATE_INT) !== false && (int)$age >= 0) {
    echo "有効な年齢です";
}

ミス2:empty()"0"を弾いてしまう

if (!empty($value) && is_numeric($value)) {
    echo "OK";
}

このコードでは、"0"が通りません。

修正するなら、次のようにします。

if ($value !== '' && is_numeric($value)) {
    echo "OK";
}

ミス3:郵便番号や電話番号を数値として扱う

$tel = "09012345678";

if (is_numeric($tel)) {
    $tel = (int) $tel;
}

電話番号を数値に変換するのは避けましょう。

電話番号は計算する値ではなく、文字列として保持すべき情報です。

$tel = "09012345678";

if (preg_match('/^0\d{9,10}$/', $tel)) {
    echo "電話番号として有効です";
}

まとめ

is_numeric()は、値が数値型、またはPHPのルールで数値として扱える文字列かどうかを判定する関数です。

var_dump(is_numeric(123));      // true
var_dump(is_numeric("123"));    // true
var_dump(is_numeric("12.3"));   // true
var_dump(is_numeric("1e3"));    // true
var_dump(is_numeric("abc"));    // false
var_dump(is_numeric("123abc")); // false

便利な関数ですが、整数だけを判定する関数ではない点に注意が必要です。

特に、フォーム入力のバリデーションでは、次のように目的に応じて使い分けることが重要です。

目的おすすめの方法
数値として計算できるか確認したいis_numeric()
整数だけ許可したいfilter_var()または正規表現
小数は許可し、指数表記は拒否したい正規表現
数字だけの文字列か確認したいctype_digit()
郵便番号・電話番号を検証したい正規表現
全角数字を許可したいmb_convert_kana()で変換してから判定
カンマ区切りの金額を扱いたいカンマの形式を検証してから処理

is_numeric()は、数値チェックの入口として便利な関数です。

ただし、年齢・数量・金額・電話番号・郵便番号など、入力項目ごとに許可したい形式は異なります。

そのため実務では、単にis_numeric()を使うだけでなく、
「どのような数値を許可するのか」
「小数や指数表記を認めるのか」
「先頭ゼロや全角数字をどう扱うのか」
を明確にしたうえで、適切なバリデーション方法を選ぶことが大切です。

以上、PHPのis_numeric関数についてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次