🖼️
【PHP】データベースに保存した画像を表示させる
はじめに
これが私の人生初の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