【PHP】フォームで送信されたチェックボックスの値が空になる理由と対策

【PHP】フォームで送信されたチェックボックスの値が空になる理由と対策 PHP

WebフォームをPHPで処理していると、「チェックボックスの値が空になる」「未チェックだと値が送信されない」という現象に遭遇したことがある方も多いのではないでしょうか。この記事では、チェックボックスが空になる理由と、その対策方法について解説します。

チェックボックスの仕組みを理解しよう

HTMLにおけるチェックボックス()は、チェックされたときだけ値が送信されるという仕様になっています。つまり、チェックされていなければ、その名前(name属性)ごとPOSTやGETに含まれません。

<input type="checkbox" name="agree" value="yes"> 利用規約に同意する

この状態でチェックが入っていれば、PHPでは次のように受け取れます。

$_POST['agree']; // "yes"

一方、チェックが入っていなければ $_POST[‘agree’] は存在しません。値が「空」なのではなく、「そもそも送られていない」のです。

issetやemptyでの判定に注意

未チェックの場合、isset($_POST[‘agree’]) は false を返します。一方で、以下のようなコードを書いてしまうと、未チェック時にエラーになる可能性があります。

if ($_POST['agree'] === 'yes') {
  // 実行されない
}

この場合、$_POST[‘agree’] が未定義のため「undefined index」の警告が出る可能性があります。

安全に値を判定する方法

チェックボックスの値を扱う場合は、isset() や array_key_exists() を使って存在を確認するのが安全です。

if (isset($_POST['agree']) && $_POST['agree'] === 'yes') {
  echo "同意されました。";
} else {
  echo "同意が必要です。";
}

もしくは三項演算子を使って初期値を設定する方法も便利です。

$agree = isset($_POST['agree']) ? $_POST['agree'] : 'no';

未チェック時にも値を送信させる方法(HTML側の対策)

HTML側で未チェックの状態でも値を送信したい場合、同じ name を持つ 隠しフィールド(hidden) を事前に設置する方法があります。

<input type="hidden" name="agree" value="no">
<input type="checkbox" name="agree" value="yes"> 利用規約に同意する

この場合、チェックされれば「yes」が送信され、されなければ「no」が送られます。
チェックボックスが後に定義されていれば、その値が優先されます。

チェックボックスが複数ある場合の注意点

複数のチェックボックスを扱う場合、name属性に [] を付けて配列で受け取るのが一般的です。

<input type="checkbox" name="options[]" value="A"> A  
<input type="checkbox" name="options[]" value="B"> B  
<input type="checkbox" name="options[]" value="C"> C

PHPではこのように受け取ります。

$selected = isset($_POST['options']) ? $_POST['options'] : [];
foreach ($selected as $option) {
  echo htmlspecialchars($option) . "<br>";
}

チェックが1つもされていない場合は $_POST[‘options’] 自体が存在しないため、空配列を初期値として設定しておくと安全です。

まとめ

チェックボックスが空になるのは「チェックされていない場合、値自体が送信されない」というHTMLの仕様によるものです。PHPで扱う際は、isset() で存在確認を行うこと、もしくは隠しフィールドでデフォルト値を送信することで、意図しない不具合を防ぐことができます。フォーム処理の安定性を高めるためにも、ぜひこれらの対策を取り入れてみてください。