文字だけの掲示板もいいですが、やっぱり「写真」が欲しいですよね。
今回は、ユーザーが選んだ画像をサーバーにアップロードして表示する機能を作ります。
文字(テキスト)を送る時とはルールが全く違うので、一つずつ確認していきましょう。
HTML側のルール:魔法の呪文「enctype」
画像を送信するフォームを作る時、<form> タグに必ず追加しなければならない属性があります。
<!-- これがないと画像は送れません! -->
<form method="post" enctype="multipart/form-data">
<input type="file" name="image">
<button type="submit">アップロード</button>
</form>
enctype="multipart/form-data"(エンタイプ・マルチパート・フォームデータ)
これを書き忘れると、ファイルを選択してもファイル名(文字)だけが送られてしまい、画像の中身が届きません。
「画像を送る時はエンタイプ!」と覚えましょう。
PHP側のルール:$_POSTではなく「$_FILES」
画像データは、いつもの $_POST ではなく、$_FILES(ファイルズ) という特別な箱に入って届きます。
この箱の中身は、少し複雑な構造になっています。
| キー | 意味 | 例 |
|---|---|---|
['name'] |
元のファイル名 | photo.jpg |
['type'] |
ファイルの種類 | image/jpeg |
['tmp_name'] |
一時保存場所 (重要!) |
C:\xampp\tmp\phpA1.tmp |
['size'] |
ファイルサイズ | 10240 (バイト) |
一時保存場所(tmp_name)とは?
アップロードされた画像は、まずサーバーの「一時フォルダ」という場所に、適当な名前で仮置きされます。
これを正しい場所に移動(保存)させるのがPHPの仕事です。
画像を保存する「move_uploaded_file」
画像を正式に保存するには、以下の関数を使います。
move_uploaded_file( 仮置き場所, 保存したい場所 );
ファイル名の重複問題
もしみんなが「image.jpg」という名前でアップしたら、上書きされて消えてしまいます。
そこで、保存する時は「絶対に被らない名前」を自動生成するのが鉄則です。
// 現在時刻などを元にユニークなIDを作る
$new_filename = uniqid() . ".jpg";
実践:画像アップローダーを作ろう
では、画像をアップロードして、その場ですぐに表示するアプリを作ってみましょう。
準備: htdocs フォルダの中に images という名前の空フォルダを作ってください。
<?php
$message = "";
$uploaded_image = "";
// 送信ボタンが押された時
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// ファイルが正しく送られたかチェック
// (error === 0 なら成功という意味)
if (isset($_FILES['upfile']) && $_FILES['upfile']['error'] === 0) {
// 1. アップロードされたファイルの情報を取得
$file = $_FILES['upfile'];
$tmp_path = $file['tmp_name']; // 仮置き場
// 2. 新しいファイル名を決める(ユニークID + 元の拡張子だと尚良し)
// 今回は簡易的に .jpg 固定にします
$save_filename = uniqid() . ".jpg";
// 3. 保存先を決める(imagesフォルダの中)
$save_path = 'images/' . $save_filename;
// 4. ファイルを移動(保存)する!
if (move_uploaded_file($tmp_path, $save_path)) {
$message = "アップロード成功!";
$uploaded_image = $save_path; // 表示用にパスを残す
} else {
$message = "アップロードに失敗しました...";
}
} else {
$message = "ファイルが選択されていません。";
}
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>画像アップロード</title>
</head>
<body>
<h1>画像アップロード</h1>
<p><?= $message ?></p>
<!-- enctypeを忘れずに! -->
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="upfile" accept="image/*">
<button type="submit">送信</button>
</form>
<hr>
<!-- 画像があれば表示する -->
<?php if ($uploaded_image): ?>
<p>アップロードされた画像:</p>
<img src="<?= $uploaded_image ?>" width="300">
<?php endif; ?>
</body>
</html>
解説と注意点
- 権限(パーミッション):
Mac(MAMP)の人は、imagesフォルダに書き込み権限がないと失敗することがあります。フォルダを右クリック→「情報を見る」から、全員「読み/書き」ができるように設定してください。 - データベースとの連携:
実務では、画像ファイルそのものはサーバーのフォルダ(今回ならimages)に入れ、「ファイル名(xxxx.jpg)」だけをデータベースに保存します。
DBに画像を直接保存するのは重くなるのでやりません。
まとめ
- フォームには
enctype="multipart/form-data"をつける。 - データは
$_FILESで受け取る。 move_uploaded_file()で一時フォルダから移動させる。- ファイル名は
uniqid()などでランダムにする。
これで、あなたの作ったアプリに「彩り」が加わりますね!
次回は、ログイン機能を作るための第一歩、「パスワードのハッシュ化(暗号化)」について解説します。
セキュリティの必須知識ですよ!
📝 今日のミニテスト
画像処理の重要ポイント!
Q1. 画像を送信するフォームに絶対必要な属性は?
正解:enctype="multipart/form-data"
「マルチパート」と覚えましょう。これがないとファイルが届きません。
Q2. アップロードされたファイルの情報が入っているスーパーグローバル変数は?
正解:$_FILES
$_POST には入りません。var_dump($_FILES) で中身を見てみると面白いですよ。
Q3. 画像ファイルそのものは、通常どこに保存する?
正解:サーバーの特定のフォルダ(imagesなど)
データベースには「ファイル名(パス)」だけを保存するのが一般的です。