PHPの入力チェックを整理する|空文字・数値・日付をどう見る?

こんにちは、さるまりんです 🐒🔧

PHPでフォームやAPIの入力値を扱っていると、

  • 未入力かどうかを確認したい
  • 数値として扱えるか確認したい
  • 日付として正しいか確認したい
  • empty()isset() の違いで迷う

こんな場面がよくあります。

入力チェックは、

「何を確認したいのか」

を先に考えることが大切ですね。

関数を覚えるだけではなく、それがどういう意味なのかが重要だと思っています。

今回は、PHPの入力チェックについて、空文字・数値・日付を中心に整理してみます。


入力チェックは「何を確認したいか」から考えよう

入力チェックを書くとき、いきなり「どの関数だっけ?」とスタートすると迷いやすい気がします。

たとえば、次のような値があったとします。

$value = $_POST['age'] ?? null;

このとき、確認したいことは何か?

いくつかのパターンが考えられます。

  • 値が送られてきているか
  • 空文字ではないか
  • 数値として扱えるか
  • 整数として扱えるか
  • この入力として許可できる範囲か

同じ「年齢チェック」でも、見たいことはひとつではありません。

そのためには、まず

この入力に対して、何を保証するのか

を分けて考えると、コードも読みやすくなりますね。


isset() は「存在するか」を見る

isset() は、変数が存在していて、かつ null ではないかを確認します。

「あるの?」で、「ちゃんと何か持っているの?」ということですね。

$name = $_POST['name'] ?? null;

if (isset($name)) {
    echo '値は存在しています';
}

isset() は、空文字かどうかまでは見ていません。

たとえば、次のような値は isset() では true になります。

$value = '';

var_dump(isset($value)); // true

空文字でも、変数としては存在しているからです。

そのため、isset() は、

  • そもそも値があるか
  • null ではないか

を確認したいときに使うものです。

この「空文字列はどっちだっけ?」が、なかなか覚えられないんですけどね。


empty() は便利だけど「0」に注意する

empty() は、値が「空っぽ」かどうかを確認するために使われます。

$name = '';

if (empty($name)) {
    echo '名前が入力されていません';
}

ただし、ちょっと注意。

empty() は便利だけど、落とし穴があります。

PHPでは、次のような値が empty() で true になります。

var_dump(empty(''));   // true
var_dump(empty(null)); // true
var_dump(empty([]));   // true
var_dump(empty('0'));  // true
var_dump(empty(0));    // true

そう、'0' も空として扱われるんです。

たとえば、数量や金額などで 0 を有効な値として扱いたい場合、empty() を使うと思ってもいない動作になることがあります。

$quantity = '0';

if (empty($quantity)) {
    echo '数量が入力されていません';
}

このコードでは、'0' が入力されていても「未入力」と判定されます。

フォームの種類によっては、これは困ることがあります。

なので、empty() は、

  • 0 を空として扱ってよいか
  • 空文字と null を同じ扱いにしてよいか

を考えてから使うと安心です。

empty()、まさに「空っぽ」の判定です。

0 も空文字列も空配列も空っぽとして扱われるので、便利なぶん、意味をわかったうえで使いたいですね。


trim() で前後の空白を取り除く

入力チェックでは、空白だけの入力にも注意が必要です。

$name = '   ';

if ($name === '') {
    echo '名前が入力されていません';
}

この場合、見た目は何も入力されていないように見えても、実際には半角スペースが並んでいます。

そのため、$name === '' では未入力として判定できません。

そこで、trim() を使って前後の空白を取り除きます。

$name = '   ';
$name = trim($name);

if ($name === '') {
    echo '名前が入力されていません';
}

入力値をチェックするときは、先に trim() してから判定すると、意図がはっきりします。

ただし、パスワードのように空白自体が意味を持つ可能性のある項目では、勝手に trim() してよいか注意が必要です。

パスワードに空白を許すかというのはまた別の議論として、入力項目によって、空白をどう扱うかを考えることが大切です。

また、ここで扱っているのは主に半角スペースの例です。全角スペースも空として扱いたい場合は、別途置き換えや正規表現などを組み合わせることもあります。


空文字チェックは明示的に書くと読みやすい

0 を有効な値として扱いたい場合は、empty() よりも明示的に空文字をチェックした方がわかりやすいです。

$value = $_POST['quantity'] ?? null;

if ($value === null || trim($value) === '') {
    echo '数量が入力されていません';
}

この書き方なら、'0' は空として扱われません。

trim() もしているので、半角スペースだけの入力も考慮されています。

$value = '0';

var_dump(trim($value) === ''); // false

少し長く見えますが、

  • null なら未入力
  • 空文字なら未入力
  • '0' は入力あり

という意図が読みやすくなります。

やりたいことがちゃんと書ける。大切ですね。


数値チェックは is_numeric() だけで終わらせない

数値として扱えるかどうかを確認したいとき、is_numeric() を使うことがあります。

$age = '20';

if (is_numeric($age)) {
    echo '数値として扱えます';
}

is_numeric() は、数値または数値形式の文字列であれば true を返します。

var_dump(is_numeric('20'));   // true
var_dump(is_numeric('20.5')); // true
var_dump(is_numeric('abc'));  // false

ただ、ここでも考えたいことがあります。

たとえば年齢なら、小数は許可したくないかもしれません。

$age = '20.5';

if (is_numeric($age)) {
    echo '数値として扱えます';
}

このコードでは '20.5' も数値として扱えます。

しかし、年齢の入力としては不自然な場合が多そうです。

20歳と6か月を 20.5 と表すこともあるかもしれませんが、一般的な年齢入力では整数にしたいことが多いですよね。

つまり、数値チェックでは、

  • 数値として扱えればよいのか
  • 整数である必要があるのか
  • 0以上である必要があるのか
  • 上限や下限があるのか

まで考える必要があります。


整数チェックには filter_var() も使える

整数として正しいかを確認したい場合は、filter_var() を使う方法もあります。

$age = '20';

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

範囲を指定することもできます。

$age = '20';

$options = [
    'options' => [
        'min_range' => 0,
        'max_range' => 120,
    ],
];

if (filter_var($age, FILTER_VALIDATE_INT, $options) !== false) {
    echo '年齢として扱えそうです';
}

このようにすると、単に「数値か」だけではなく、この変数の意味に合った範囲も含めて確認できます。

入力チェックでは、この「どう扱うか」がとても大切です。


日付チェックは DateTime を使って確認する

日付の入力チェックもよく出てきます。

たとえば、次のような値です。

$date = '2026-05-25';

日付らしい文字列かどうかを見るだけなら、正規表現でもある程度は確認できます。

$date = '2026-05-25';

if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
    echo '形式は yyyy-mm-dd です';
}

ただし、正規表現だけでは、その日付が本当に存在するかまでは確認できません。

たとえば、次の値は形式としては合っています。

$date = '2026-02-31';

でも、2月31日は存在しません。

そこで、DateTime::createFromFormat() を使って確認します。

function isValidDate(string $date): bool
{
    $dt = DateTime::createFromFormat('Y-m-d', $date);

    return $dt !== false && $dt->format('Y-m-d') === $date;
}

var_dump(isValidDate('2026-05-25')); // true
var_dump(isValidDate('2026-02-31')); // false

ポイントは、作成した日付をもう一度同じ形式で戻して、元の文字列と一致するか確認しているところです。

PHPの日時処理では、存在しない日付が補正されることがあります。

たとえば、4月31日を5月1日のように扱うケースです。

そのため、createFromFormat() で作れたかだけではなく、結果が元の入力と一致するかも見ておくと安心です。


小さな入力チェック関数に分けてみる

ここまで見てきた内容を、小さな関数として整理してみます。

ここでは、フォームから受け取った値を文字列として扱う前提にしています。

function isFilled(?string $value): bool
{
    return $value !== null && trim($value) !== '';
}

function isValidIntegerRange(string $value, int $min, int $max): bool
{
    $options = [
        'options' => [
            'min_range' => $min,
            'max_range' => $max,
        ],
    ];

    return filter_var($value, FILTER_VALIDATE_INT, $options) !== false;
}

function isValidDate(string $date): bool
{
    $dt = DateTime::createFromFormat('Y-m-d', $date);

    return $dt !== false && $dt->format('Y-m-d') === $date;
}

使う側はこのようになります。

$name = $_POST['name'] ?? null;
$age = $_POST['age'] ?? null;
$birthday = $_POST['birthday'] ?? null;

$errors = [];

if (!is_string($name) || !isFilled($name)) {
    $errors[] = '名前を入力してください';
}

if (!is_string($age) || !isFilled($age) || !isValidIntegerRange($age, 0, 120)) {
    $errors[] = '年齢は0から120までの整数で入力してください';
}

if (!is_string($birthday) || !isFilled($birthday) || !isValidDate($birthday)) {
    $errors[] = '生年月日は yyyy-mm-dd の形式で入力してください';
}

if (!empty($errors)) {
    foreach ($errors as $error) {
        echo $error . PHP_EOL;
    }
}

$_POST の値は、通常は文字列として扱うことが多いですが、同じ名前のフォーム項目が配列として送られてくる場合もあります。

そのため、ここでは is_string() で文字列かどうかも確認しています。

実際の開発では、フレームワークのバリデーション機能を使うことが多いです。

でも、こうした小さなチェックの意味を理解しておくと、フレームワークを使うときにも、AIが出したコードを読むときにも、判断しやすくなりますよ。

自分が何をしているかを知っていることは、とっても大事です。


入力チェックで大切なのは「値の意味」を考えること

入力チェックでは、つい関数名から考えたくなります。

  • empty() を使えばいいのか
  • isset() を使えばいいのか
  • is_numeric() で足りるのか

もちろん、関数の使い方を知ることは大切です。

でも、それ以上に大事なのは、

その値を、システムの中でどう扱いたいのか

だと思います。

たとえば、同じ 0 でも、

  • 数量なら有効な値かもしれない
  • 選択肢の未選択を表す値かもしれない
  • この入力では許可したくない値かもしれない

というように、意味は場面によって変わります。

だからこそ、入力チェックは単なる文法ではなく、少し設計に近いものだと感じます。


まとめ

今回は、PHPの入力チェックについて整理してみました。

  • isset() は存在していて null ではないかを見る
  • empty() は便利だが '0' も空扱いになる
  • trim() を使うと空白だけの入力を扱いやすい
  • 数値チェックでは、整数か、範囲はどうかまで考える
  • 日付チェックでは、形式だけでなく実在する日付かも見る

入力チェックは、地味ですがとても大切な処理です。

なんとなく関数を選ぶのではなく、

「この入力に対して、何を確認したいのか」

から考えると、コードの意図もはっきりしてきます。

AIにコードを書いてもらう場面が増えても、この視点があると、出てきたコードをそのまま使うのではなく、ちゃんと読んで判断しやすくなります。

AIに「調査して直して」とお願いしても、ちゃんと思ったように直したかを確認できるということですね。

小さな入力チェックから、安心して扱えるPHPコードにしていきたいです。

読んでくださってありがとうございました。
それではまた!