🖼️

【PHP】データベースに保存した画像を表示させる

2024/06/21に公開

はじめに

これが私の人生初のzenn記事です。

phpMyAdminのデータベースに保存した画像を
ブラウザに表示させるのに相当苦戦したので、
「このコードで表示できました」というメモ用として書きます。
※正確な表現ができていない箇所があります。悪しからず。

誰向け

・初心者
※画像のバイナリデータ(文字化けのようなデータ)を
保存までできた方
※苦戦した箇所にコメントを書いているので、
それ以外を知りたい方の役には立ちにくいと思います。

読むメリット

・phpMyAdminのデータベースに保存した画像を
ブラウザに表示させることができる

表示の流れ(read.phpファイル参照)

1.バイナリデータを取り出す

※バイナリデータ:文字化けのようなデータ

2.base64形式に変換

※base64:データを変換する方法のひとつ

3.imgタグに入れる(base64形式用の書き方で)

※他の方法もあると思いますが、今回はこの1,2,3の方法について。

DBのテーブルの構造

# 名前 タイプ 照合順序 ・・・ その他
1 id int(11) ・・・ AUTO_INCREMENT
2 title varchar(64) utf8mb4_bin ・・・
3 picture mediumblob ・・・
4 created_at datetime ・・・
5 updated_at datetime ・・・

コード全体(3つファイル使用)

input.phpファイル(「input」は任意の名前)

input.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>入力画面</title>
</head>
<body>
    //「enctype="multipart/form-data"」が無いと画像をフォーム送信できない
    <form action="create.php" method="POST" enctype="multipart/form-data">
        <fieldset>
            <legend>入力画面</legend>
            <a href="read.php">一覧画面</a>
            <div>
                title: <input type="text" name="taitoru">
            </div>
            <div>
                picture: <input type="file" name="gazou">
            </div>
            <div>
                <button>submit</button>
            </div>
        </fieldset>
    </form>
</body>
</html>

create.phpファイル(「create」は任意の名前)

create.php
<?php
if (
    !isset($_POST['taitoru']) || $_POST['taitoru'] === ''
    || !isset($_FILES['gazou']) || $_FILES['gazou'] === ''
) {
    exit('入力されていません');
}
$taitoru = $_POST['taitoru'];
$gazou = $_FILES['gazou'];

// 各種項目設定
$dbn = 'mysql:dbname=自分で作ったDB名;charset=utf8mb4;port=3306;host=localhost';
$user = 'root';
$pwd = '';

// DB接続
try {
    $pdo = new PDO($dbn, $user, $pwd);
} catch (PDOException $e) {
    echo json_encode(["db error" => "{$e->getMessage()}"]);
    exit();
}

if ($_SERVER['REQUEST_METHOD'] != 'POST') {
} else {
    if (!empty($_FILES['gazou']['name'])) {
    //['gazou']['tmp_name']は画像のパス
        $content = file_get_contents($_FILES['gazou']['tmp_name']);
        // 画像を保存
        $sql = 'INSERT INTO 自分で作ったテーブル名 (id, title, picture, created_at, updated_at) VALUES (NULL, :title, :picture, now(), now())';
        $stmt = $pdo->prepare($sql);

        $stmt->bindValue(':title', $taitoru, PDO::PARAM_STR);
        // 画像データをバイナリ形式でデータベースに挿入
        $stmt->bindValue(':picture', file_get_contents($_FILES['gazou']['tmp_name']), PDO::PARAM_LOB);

        // SQL実行(実行に失敗すると `sql error ...` が出力される)
        try {
            $status = $stmt->execute();
        } catch (PDOException $e) {
            echo json_encode(["sql error" => "{$e->getMessage()}"]);
            exit();
        }
    }
}
//⇒うまくいけば入力画面でsubmitしたデータがDBのテーブルに保存される
header('Location:input.php');
exit();

read.phpファイル(「read」は任意の名前)

read.php
<?php
// DB接続
$dbn = 'mysql:dbname=自分で作ったDB名;charset=utf8mb4;port=3306;host=localhost';
$user = 'root';
$pwd = '';

try {
    $pdo = new PDO($dbn, $user, $pwd);
} catch (PDOException $e) {
    echo json_encode(["db error" => "{$e->getMessage()}"]);
    exit();
}

// SQL作成
$sql = 'SELECT * FROM 自分で作ったテーブル名 ORDER BY created_at ASC';

$stmt = $pdo->prepare($sql);

// SQL実行
try {
    $stmt->execute();
} catch (PDOException $e) {
    echo json_encode(["sql error" => "{$e->getMessage()}"]);
    exit();
}

//1.バイナリデータを取り出す!!!
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);

$output = "";
foreach ($result as $record) {

    //2.取得した画像バイナリデータをbase64で変換!!!
    $img = "data:image/jpeg;base64," . base64_encode($record["picture"]);
    }
?>

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>一覧画面</title>
</head>
<body>
    <fieldset>
        <legend>一覧画面</legend>
        <a href="input.php">入力画面</a>

        <!-- 3.imgタグに入れる!!! -->
        <img src=<?= $img ?> class="topimage" alt="top" />
        <table>
            <thead>
                <tr>
                    <th>title</th>
                    <th>picture</th>
                </tr>
            </thead>
            <tbody>
                <?= $output ?>
            </tbody>
        </table>
    </fieldset>
    <script>
        const pictures = <?= json_encode($result) ?>;
        console.log(pictures);
    </script>
</body>
</html>  

ブラウザ画面の流れ


①フォーム入力

②「submit」ボタンクリック

③データベースのテーブルにデータが保存される

④「一覧画面」クリック⇒画像出た!

まとめ

1.バイナリデータを取り出す
2.base64形式に変換
3.imgタグに入れる(base64形式用の書き方で)
をすれば画像表示できる(read.phpファイルで)

Discussion