はじめに
前回の記事ではWeb制作でよく使うCSS小技をスニペット集としてまとめました。今回はPHPのセッションを使ってフォームの選択状態を保持する方法を解説します。「検索フィルターで絞り込んだ条件をページをまたいでも維持したい」「ページを戻ったときにラジオボタンの選択が消えていた」という場面はWeb制作でよく登場します。チェックボックス・セレクトボックス・ラジオボタンそれぞれの扱い方を丁寧に解説します。
1. セッションとは何か
1.1 セッションの基本概念
セッション(Session):
ユーザーがサイトを訪問している間
サーバー側にデータを一時的に保存する仕組み。
ブラウザを閉じると消える(デフォルト)。
例えるなら:
→ お店に入ったとき渡される番号札のようなもの
→ 番号(セッションID)をブラウザが持ち
サーバー側に対応するデータが保存される
使う場面:
→ ログイン状態の保持
→ ショッピングカートの中身
→ フォームの入力内容の保持 ← 今回のテーマ
→ 検索フィルターの条件の保持
cookieとの違い:
→ cookie :ブラウザ(クライアント側)に保存
→ session :サーバー側に保存
→ sessionの方がセキュリティ面で安全
1.2 セッションの基本的な使い方
<?php
// ① セッションを開始する(すべてのページの先頭に書く)
session_start();
// ② データを保存する
$_SESSION['username'] = '山田太郎';
$_SESSION['age'] = 30;
// ③ データを取得する
echo $_SESSION['username']; // 山田太郎
// ④ データを削除する
unset( $_SESSION['username'] );
// ⑤ セッションをすべて破棄する(ログアウト時など)
session_destroy();
?>
<!--
重要なルール:
session_start() は
→ HTMLを出力する前に書く
→ すべてのページの一番上に書く
→ 1ページに1回だけ書く
-->
2. ラジオボタンの選択をセッションで保持する
2.1 HTMLフォーム
<?php session_start(); ?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ラジオボタンのセッション保持</title>
</head>
<body>
<form method="post" action="confirm.php">
<p>ご希望のプランを選択してください</p>
<?php
// セッションに保存された値を取得する
// 保存されていない場合は空文字をデフォルト値にする
$selected_plan = $_SESSION['plan'] ?? '';
?>
<label>
<input
type="radio"
name="plan"
value="basic"
<?php echo $selected_plan === 'basic' ? 'checked' : ''; ?>
>
ベーシックプラン(月額980円)
</label>
<label>
<input
type="radio"
name="plan"
value="standard"
<?php echo $selected_plan === 'standard' ? 'checked' : ''; ?>
>
スタンダードプラン(月額1,980円)
</label>
<label>
<input
type="radio"
name="plan"
value="premium"
<?php echo $selected_plan === 'premium' ? 'checked' : ''; ?>
>
プレミアムプラン(月額3,980円)
</label>
<button type="submit">次へ進む</button>
</form>
</body>
</html>
2.2 送信先のPHP処理
<?php
// confirm.php
session_start();
// POSTデータが送られてきた場合に処理する
if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) {
// ラジオボタンの値を取得してセッションに保存する
// filter_input でセキュリティ対策をする
$plan = filter_input( INPUT_POST, 'plan', FILTER_SANITIZE_SPECIAL_CHARS );
// 許可する値のリスト(バリデーション)
$allowed_plans = [ 'basic', 'standard', 'premium' ];
if ( in_array( $plan, $allowed_plans, true ) ) {
// 許可された値だけセッションに保存する
$_SESSION['plan'] = $plan;
}
}
// セッションから値を取得する
$selected_plan = $_SESSION['plan'] ?? '';
// プランのラベルを表示用に変換する
$plan_labels = [
'basic' => 'ベーシックプラン(月額980円)',
'standard' => 'スタンダードプラン(月額1,980円)',
'premium' => 'プレミアムプラン(月額3,980円)',
];
$plan_label = $plan_labels[ $selected_plan ] ?? '未選択';
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>確認ページ</title>
</head>
<body>
<h1>選択内容の確認</h1>
<p>選択プラン:<?php echo htmlspecialchars( $plan_label ); ?></p>
<!-- 戻るボタン(セッションが保持されているので選択が残る) -->
<a href="form.php">← 戻って変更する</a>
<form method="post" action="complete.php">
<button type="submit">この内容で申し込む</button>
</form>
</body>
</html>
💡 htmlspecialchars() は必ず使う: セッションから取り出した値をHTMLに出力するときは htmlspecialchars() でエスケープしてXSS(クロスサイトスクリプティング)を防ぎます。
3. セレクトボックス(コンボボックス)の選択をセッションで保持する
3.1 HTMLフォーム
<?php session_start(); ?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>セレクトボックスのセッション保持</title>
</head>
<body>
<form method="post" action="search.php">
<p>条件を選択して検索してください</p>
<?php
// セッションから値を取得する
$selected_category = $_SESSION['category'] ?? '';
$selected_price = $_SESSION['price'] ?? '';
$selected_sort = $_SESSION['sort'] ?? 'newer';
?>
<!-- カテゴリー -->
<label for="category">カテゴリー</label>
<select id="category" name="category">
<option value="">すべて</option>
<option value="web" <?php echo $selected_category === 'web' ? 'selected' : ''; ?>>Web制作</option>
<option value="app" <?php echo $selected_category === 'app' ? 'selected' : ''; ?>>アプリ開発</option>
<option value="design" <?php echo $selected_category === 'design' ? 'selected' : ''; ?>>デザイン</option>
<option value="other" <?php echo $selected_category === 'other' ? 'selected' : ''; ?>>その他</option>
</select>
<!-- 価格帯 -->
<label for="price">価格帯</label>
<select id="price" name="price">
<option value="">指定なし</option>
<option value="under10k" <?php echo $selected_price === 'under10k' ? 'selected' : ''; ?>>1万円未満</option>
<option value="10k-50k" <?php echo $selected_price === '10k-50k' ? 'selected' : ''; ?>>1万円〜5万円</option>
<option value="over50k" <?php echo $selected_price === 'over50k' ? 'selected' : ''; ?>>5万円以上</option>
</select>
<!-- 並び順 -->
<label for="sort">並び順</label>
<select id="sort" name="sort">
<option value="newer" <?php echo $selected_sort === 'newer' ? 'selected' : ''; ?>>新しい順</option>
<option value="older" <?php echo $selected_sort === 'older' ? 'selected' : ''; ?>>古い順</option>
<option value="popular" <?php echo $selected_sort === 'popular' ? 'selected' : ''; ?>>人気順</option>
</select>
<button type="submit">検索する</button>
</form>
</body>
</html>
3.2 送信先のPHP処理
<?php
// search.php
session_start();
if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) {
// 許可する値のリスト
$allowed_categories = [ '', 'web', 'app', 'design', 'other' ];
$allowed_prices = [ '', 'under10k', '10k-50k', 'over50k' ];
$allowed_sorts = [ 'newer', 'older', 'popular' ];
// カテゴリー
$category = filter_input( INPUT_POST, 'category', FILTER_SANITIZE_SPECIAL_CHARS );
if ( in_array( $category, $allowed_categories, true ) ) {
$_SESSION['category'] = $category;
}
// 価格帯
$price = filter_input( INPUT_POST, 'price', FILTER_SANITIZE_SPECIAL_CHARS );
if ( in_array( $price, $allowed_prices, true ) ) {
$_SESSION['price'] = $price;
}
// 並び順(デフォルト値を設定する)
$sort = filter_input( INPUT_POST, 'sort', FILTER_SANITIZE_SPECIAL_CHARS );
if ( in_array( $sort, $allowed_sorts, true ) ) {
$_SESSION['sort'] = $sort;
} else {
$_SESSION['sort'] = 'newer';
}
}
// セッションから検索条件を取得して検索処理を行う
$category = $_SESSION['category'] ?? '';
$price = $_SESSION['price'] ?? '';
$sort = $_SESSION['sort'] ?? 'newer';
/*
ここで $category・$price・$sort を使って
データベース検索などの処理を行う
*/
?>
4. チェックボックスの選択をセッションで保持する
4.1 チェックボックスの特殊な挙動
チェックボックスの注意点:
ラジオボタンやセレクトボックスと違い
チェックボックスは「チェックなし」のとき
POSTデータに何も送られない。
例:
チェックあり → $_POST['agree'] = 'on'(値が送られる)
チェックなし → $_POST['agree'] が存在しない(何も送られない)
→ isset() や null合体演算子(??)で
存在チェックをする必要がある
複数のチェックボックスは配列で送る:
<input type="checkbox" name="tags[]" value="php">
<input type="checkbox" name="tags[]" value="css">
→ $_POST['tags'] = ['php', 'css'] のように配列で届く
4.2 単体のチェックボックス
<?php session_start(); ?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>チェックボックスのセッション保持</title>
</head>
<body>
<form method="post" action="result.php">
<?php
// セッションから値を取得する
// チェックボックスは true/false で管理する
$agreed = $_SESSION['agreed'] ?? false;
$subscribe = $_SESSION['subscribe'] ?? false;
?>
<!-- 利用規約への同意 -->
<label>
<input
type="checkbox"
name="agreed"
value="1"
<?php echo $agreed ? 'checked' : ''; ?>
>
利用規約に同意する
</label>
<!-- メルマガ購読 -->
<label>
<input
type="checkbox"
name="subscribe"
value="1"
<?php echo $subscribe ? 'checked' : ''; ?>
>
メールマガジンを購読する
</label>
<button type="submit">送信する</button>
</form>
</body>
</html>
4.3 複数チェックボックスの処理
<?php session_start(); ?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>複数チェックボックスのセッション保持</title>
</head>
<body>
<form method="post" action="filter.php">
<p>興味のある分野を選択してください(複数選択可)</p>
<?php
// セッションから配列を取得する
// 保存されていない場合は空配列をデフォルト値にする
$selected_tags = $_SESSION['tags'] ?? [];
?>
<?php
// チェックボックスの選択肢を定義する
$tag_options = [
'php' => 'PHP',
'javascript' => 'JavaScript',
'css' => 'CSS',
'wordpress' => 'WordPress',
'react' => 'React',
'python' => 'Python',
];
foreach ( $tag_options as $value => $label ) :
// セッションの配列にこの値が含まれているか確認する
$is_checked = in_array( $value, $selected_tags, true );
?>
<label>
<input
type="checkbox"
name="tags[]"
value="<?php echo htmlspecialchars( $value ); ?>"
<?php echo $is_checked ? 'checked' : ''; ?>
>
<?php echo htmlspecialchars( $label ); ?>
</label>
<?php endforeach; ?>
<button type="submit">絞り込む</button>
<a href="clear.php">条件をリセット</a>
</form>
</body>
</html>
4.4 送信先のPHP処理(チェックボックス)
<?php
// filter.php
session_start();
if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) {
// ===== 単体チェックボックスの処理 =====
// チェックありなら true・なしなら false を保存する
$_SESSION['agreed'] = isset( $_POST['agreed'] ) ? true : false;
$_SESSION['subscribe'] = isset( $_POST['subscribe'] ) ? true : false;
// ===== 複数チェックボックスの処理 =====
// 許可する値のリスト
$allowed_tags = [ 'php', 'javascript', 'css', 'wordpress', 'react', 'python' ];
// POSTで送られてきた配列を取得する
// チェックなしの場合は空配列になる
$posted_tags = $_POST['tags'] ?? [];
// 配列であることを確認してから処理する
if ( is_array( $posted_tags ) ) {
// 許可されている値だけを残す(バリデーション)
$safe_tags = array_filter(
$posted_tags,
fn( $tag ) => in_array( $tag, $allowed_tags, true )
);
// 配列のインデックスを振り直してからセッションに保存する
$_SESSION['tags'] = array_values( $safe_tags );
} else {
$_SESSION['tags'] = [];
}
}
// セッションから値を確認する
$agreed = $_SESSION['agreed'] ?? false;
$subscribe = $_SESSION['subscribe'] ?? false;
$tags = $_SESSION['tags'] ?? [];
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>選択結果</title>
</head>
<body>
<h1>選択内容</h1>
<p>利用規約:<?php echo $agreed ? '同意済み' : '未同意'; ?></p>
<p>メルマガ:<?php echo $subscribe ? '購読する' : '購読しない'; ?></p>
<p>興味のある分野:
<?php if ( empty( $tags ) ) : ?>
未選択
<?php else : ?>
<?php echo htmlspecialchars( implode( '・', $tags ) ); ?>
<?php endif; ?>
</p>
<a href="form.php">← 戻って変更する</a>
</body>
</html>
5. セッションのリセット
5.1 条件をリセットするページ
<?php
// clear.php
// 検索条件・フォーム入力をリセットする
session_start();
// 特定のセッション変数だけ削除する
unset( $_SESSION['category'] );
unset( $_SESSION['price'] );
unset( $_SESSION['sort'] );
unset( $_SESSION['tags'] );
unset( $_SESSION['plan'] );
unset( $_SESSION['agreed'] );
unset( $_SESSION['subscribe'] );
// 元のページにリダイレクトする
header( 'Location: form.php' );
exit;
?>
6. まとめて管理する実践パターン
6.1 フォームの状態をまとめて保存・復元する
<?php
// functions.php(共通関数ファイル)
/**
* フォームの選択状態をセッションに保存する
*/
function save_form_to_session( string $form_key, array $allowed_fields ): void {
if ( $_SERVER['REQUEST_METHOD'] !== 'POST' ) return;
foreach ( $allowed_fields as $field => $config ) {
$type = $config['type'] ?? 'string';
$allowed = $config['allowed'] ?? null;
switch ( $type ) {
// チェックボックス(単体)
case 'bool':
$_SESSION[ $form_key ][ $field ] = isset( $_POST[ $field ] );
break;
// チェックボックス(複数)
case 'array':
$values = $_POST[ $field ] ?? [];
if ( is_array( $values ) && $allowed !== null ) {
$_SESSION[ $form_key ][ $field ] = array_values(
array_filter(
$values,
fn( $v ) => in_array( $v, $allowed, true )
)
);
} else {
$_SESSION[ $form_key ][ $field ] = [];
}
break;
// ラジオボタン・セレクトボックス(単体の文字列)
default:
$value = filter_input( INPUT_POST, $field, FILTER_SANITIZE_SPECIAL_CHARS );
if ( $allowed === null || in_array( $value, $allowed, true ) ) {
$_SESSION[ $form_key ][ $field ] = $value ?? '';
}
break;
}
}
}
/**
* セッションからフォームの値を取得する
*/
function get_form_value( string $form_key, string $field, mixed $default = '' ): mixed {
return $_SESSION[ $form_key ][ $field ] ?? $default;
}
<?php
// search.php(関数を使う例)
session_start();
require_once 'functions.php';
// フォームの定義
$form_config = [
'category' => [
'type' => 'string',
'allowed' => [ '', 'web', 'app', 'design', 'other' ],
],
'price' => [
'type' => 'string',
'allowed' => [ '', 'under10k', '10k-50k', 'over50k' ],
],
'sort' => [
'type' => 'string',
'allowed' => [ 'newer', 'older', 'popular' ],
],
'tags' => [
'type' => 'array',
'allowed' => [ 'php', 'javascript', 'css', 'wordpress', 'react' ],
],
'subscribe' => [
'type' => 'bool',
],
];
// POSTデータをセッションに保存する
save_form_to_session( 'search_form', $form_config );
// セッションから値を取得する
$category = get_form_value( 'search_form', 'category', '' );
$price = get_form_value( 'search_form', 'price', '' );
$sort = get_form_value( 'search_form', 'sort', 'newer' );
$tags = get_form_value( 'search_form', 'tags', [] );
$subscribe = get_form_value( 'search_form', 'subscribe', false );
?>
7. 実践チェックリスト
✓ すべてのページの先頭に session_start() を書いているか(HTMLより前)
✓ ラジオボタン・セレクトボックスは $_SESSION['key'] ?? '' でデフォルト値を設定しているか
✓ チェックボックスは未チェック時にPOSTデータが送られないので isset() で存在確認しているか
✓ 複数チェックボックスは name="tags[]" のように [] を付けて配列で送っているか
✓ POSTで受け取った値を許可リスト($allowed)と照合してバリデーションしているか
✓ HTMLに出力するときは htmlspecialchars() でエスケープしてXSSを防いでいるか
✓ filter_input() でPOSTデータをサニタイズしてからセッションに保存しているか
✓ リセット用のページで unset() を使って特定のセッション変数だけ削除しているか
まとめ
今回はPHPのセッションを使ってフォームの選択状態を保持する方法を解説しました。ポイントをまとめると:
session_start()はHTMLより前・すべてのページの先頭に書く- セッションへの保存は
$_SESSION['key'] = $value・取得は$_SESSION['key'] ?? デフォルト値 - ラジオボタンとセレクトボックスは
$_SESSION['key'] === 'value' ? 'checked' : ''でHTML側に反映する - チェックボックスはチェックなしのときPOSTデータが送られないので
isset( $_POST['key'] )で判定する - 複数チェックボックスは
name="tags[]"で配列として送り・$_POST['tags'] ?? []で受け取る - POSTで受け取った値は必ず許可リストと照合してバリデーションしてからセッションに保存する
- HTMLへの出力は必ず
htmlspecialchars()でエスケープしてXSSを防ぐ - セッションのリセットは
unset()で特定のキーだけ削除してからリダイレクトする
次の記事では、PHPのファイル操作について解説します。ファイルの読み込み・書き込み・アップロードの実装方法をお届けします。お楽しみに!
コメント