【PHP番外編-1】掲示板に写真を載せたい!画像アップロードと$_FILESの基礎

文字だけの掲示板もいいですが、やっぱり「写真」が欲しいですよね。
今回は、ユーザーが選んだ画像をサーバーにアップロードして表示する機能を作ります。

文字(テキスト)を送る時とはルールが全く違うので、一つずつ確認していきましょう。

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>

解説と注意点

  1. 権限(パーミッション):
    Mac(MAMP)の人は、images フォルダに書き込み権限がないと失敗することがあります。フォルダを右クリック→「情報を見る」から、全員「読み/書き」ができるように設定してください。
  2. データベースとの連携:
    実務では、画像ファイルそのものはサーバーのフォルダ(今回なら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など)
データベースには「ファイル名(パス)」だけを保存するのが一般的です。

タイトルとURLをコピーしました