この記事のゴール
第4回では「Webアプリらしい」処理を入れます。
- フォームから値を送信できる
- $_GET / $_POST の扱いを理解する
- バリデーション(最低限)が書ける
- XSSを避けた表示ができる
- 次回の「DB保存(PDO)」に繋がる
1. まず理解しておくべきこと
PHPは
「フォーム入力を受け取り、処理し、HTMLを返す」
のが本業です。
そして実務では、フォーム処理が一番事故りやすいです。
- 未入力
- 想定外の文字列
- 改ざん
- XSS
- 文字コード
- バリデーション不足
今回は「最低限これだけは」というラインを固めます。
2. 今回のフォルダ構成
第3回までの構成に、フォーム用ファイルを追加します。
src/
├─ index.php
├─ add.php
└─ lib/
├─ functions.php
└─ data.php
3. add.php(タスク追加フォーム)を作る
まずは入力画面です。
src/add.php
<?php
require_once __DIR__ . "/lib/functions.php";
$title = "";
$errors = [];
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>タスク追加</title>
</head>
<body>
<h1>タスク追加</h1>
<form method="post" action="add.php">
<div>
<label>
タスク名:
<input type="text" name="title" value="<?= e($title) ?>">
</label>
</div>
<div style="margin-top: 10px;">
<button type="submit">追加</button>
</div>
</form>
<p style="margin-top: 20px;">
<a href="index.php">一覧へ戻る</a>
</p>
</body>
</html>
この時点ではまだ「入力できるだけ」です
保存は次回(第5回)でDBを使ってやります。
4. index.php にリンクを追加する
src/index.php の<h1> の下にリンクを足します。
<p><a href="add.php">+ タスクを追加</a></p>
5. POST送信を受け取る(add.phpを改造)
ここからが本題です。
src/add.php を次のように更新します。
<?php
require_once __DIR__ . "/lib/functions.php";
$title = "";
$errors = [];
if ($_SERVER["REQUEST_METHOD"] === "POST") {
// ① 入力を受け取る
$title = trim($_POST["title"] ?? "");
// ② バリデーション
if ($title === "") {
$errors[] = "タスク名を入力してください。";
}
if (mb_strlen($title) > 100) {
$errors[] = "タスク名は100文字以内で入力してください。";
}
// ③ OKなら次回はDB保存へ(今回は仮でメッセージ表示)
if (empty($errors)) {
// 本来はここでDBへINSERTする(第5回で実装)
header("Location: index.php");
exit;
}
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>タスク追加</title>
</head>
<body>
<h1>タスク追加</h1>
<?php if (!empty($errors)): ?>
<ul style="color: red;">
<?php foreach ($errors as $error): ?>
<li><?= e($error) ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<form method="post" action="add.php">
<div>
<label>
タスク名:
<input type="text" name="title" value="<?= e($title) ?>">
</label>
</div>
<div style="margin-top: 10px;">
<button type="submit">追加</button>
</div>
</form>
<p style="margin-top: 20px;">
<a href="index.php">一覧へ戻る</a>
</p>
</body>
</html>
6. ここで学ぶべき重要ポイント
6-1. $_SERVER[“REQUEST_METHOD”] を必ず見る
フォーム処理で最初にやるべきことはこれです。
if ($_SERVER["REQUEST_METHOD"] === "POST") {
...
}
- 初回表示(GET) → フォームを表示
- 送信(POST) → 入力を処理
という形になります。
6-2. $_POST[“title”] ?? “” は必須の書き方
$_POST["title"] ?? "" は、POST送信された title があればその値を取り出し、未送信や空(null)のときはエラーを出さずに空の文字列 “” を代入する安全な書き方です。
フォームは改ざんできます。
title がないようなデータが送信された場合、直接 $_POST[“title”] を呼ぶと「そんなキーはない」という警告(Undefined index)が出ます。
そのため、値がない場合に、後続の処理でエラーにならないよう、代わりの値(空文字 “”)をあらかじめ設定し
$_POST["title"] ?? ""
で安全に受け取ります。
6-3. trim は必須
ユーザーは「空白だけ」を入力できます。trimを使用する事で、空白だけ入力された場合に空白を取り除きます。
$title = trim($_POST["title"] ?? "");
trim()関数は、正確には前後の空白や改行を取り除く処理です。
前後の空白や改行を取り除く最大の理由は、ユーザーの入力ミスやコピペ時に混入した「見えない不要な空白」を取り除き、データの不整合やシステムエラーを防ぐためです。
スマホの変換やPCでのコピー&ペースト時、文字列の先頭や末尾に意図せず半角/全角スペースが入り込むことが多く、入力値チェックの誤作動防止やデータベースに登録・検索する際、メールアドレスやIDの末尾にスペースが残っていると、一致しているはずなのに「別の人・存在しないデータ」とみなされてエラーになる等のを防ぐため、基本的には入力に対してtrimしましょう。
6-4. バリデーションは「空」「長さ」から始める
最初に入れるべきバリデーションはこの2つです。
- 必須チェック
- 最大文字数
6-5. OKならリダイレクト(Post/Redirect/Get)
これを覚えておくと、実務で事故が減ります。
header("Location: index.php");
exit;
なぜ必要?
もしリダイレクトしないと、
- 送信後にブラウザ更新すると再送信される
- 二重登録の原因になる
7. ここでXSS対策を再確認する
今回、エラーメッセージ表示も
<li><?= e($error) ?></li>
にしています。
ユーザー入力ではなくても、表示する文字列は基本エスケープする癖が重要です。
8. GETについても理解しておく(超重要)
今回はPOSTで追加でしたが、一覧画面ではGETをよく使います。
例えば
- index.php?status=open
- index.php?keyword=筋トレ
のような絞り込みです。
GETとPOSTは、Webサーバーへデータを送受信する際の代表的な方式(HTTPメソッド)です。
主な違いは目的とデータの送り方で、GETはサーバーから「取得」し、POSTはサーバーへ「送信・登録」します。GETはURLにデータが露出しますが、POSTは目に見えない形でデータを送ります。
GETの受け取り例(次回以降で使う形)
$status = $_GET["status"] ?? "";
9. Laravelとの対応(ここが橋渡し)
今回のフォーム処理は、Laravelではこうなります。
| 今回のPHP | Laravel |
|---|---|
| $_POST | $request->input() |
| バリデーション | FormRequest / validate() |
| header(“Location: …”) | redirect() |
| e() | Bladeの {{ }} |
つまりLaravelは、
「この面倒な部分を安全に標準化したもの」
です。
10. 次回(第5回)でやること
いよいよDBです。
- MariaDBをDocker Composeに追加
- PDOで接続
- tasksテーブル作成
- タスク追加(INSERT)
- タスク一覧(SELECT)
- 簡易CRUDの完成
ここまで行くと、Laravelに進む準備が完全に整います。
まとめ
第4回では、
- フォーム送信(POST)
- 入力の受け取り
- バリデーション(必須・最大文字数)
- XSS対策
- リダイレクト(PRG)
を整理しました。