Baccho Log

No Image

Sponsored Link

[PHP, MySQL]画像をDBに直接保存する方法

  • 投稿日:
  • 更新日:
Tags:
MySQL PHP
Categories:
プログラミング

やりたい事

  1. フォームより画像をDBに保存をする
  2. 保存した画像をDBからWebページに表示させる

DBとTABLEを作る

MySQLを使用します。

DBを作ろう

まずは、image_db というデータベースを作成します。
文字コードはutf8
照合順序はutf8_general_ci (utf-8 で 大文字小文字の区別をしない)

CREATE DATABASE `image_db` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_general_ci`;

TABLEを作ろう

次に、image_db 内にimage_data というテーブルを作成します。
フィールド(テーブルの中身)は、

  • id(主キー Auto)
  • img
    画像データ
  • img_name
    画像名
  • user_name
    ユーザ名
CREATE TABLE `image_db`.`image_data` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `img` BLOB NOT NULL,
    `img_name` VARCHAR(255) NOT NULL,
    `user_name` VARCHAR(255) NOT NULL
) ENGINE = InnoDB;

※補足※
BLOB型について・・・
BLOB型はバイナリデータを格納するデータ型です。
4つの種類が存在しており、それぞれの格納サイズによって種類を変更します。

今回例で作成している img については BLOB なので、65535バイト(65KB)程度までの画像が格納できます。

種類 サイズ(バイト)
TINYBLOB 255
BLOB 65,535
MEDIUMBLOB 16,777,216
LONGBLOB 4,294,967,296

データを格納しよう

最終的にphpでやりますが、SQLではどのような感じで格納されるのか、一度見てみましょう。

MySQLに直打ち

それぞれのカラムにデータを格納してきます。
BLOB に画像データを格納します。

INSERT INTO `image_data` (
    `id`,
    `img`,
    `img_name`,
    `user_name`
) VALUES (
    '1',
    0x47494638396130002400f700000000000000330000660000990000cc0000ff002b00002b33002b66002b99002bcc002bff0055000055330055660055990055cc0055ff0080000080330080660080990080cc0080ff00aa0000aa3300aa6600aa9900aacc00aaff00d50000d53300d56600d59900d5cc00d5ff00ff0000ff3300ff6600ff9900ffcc00ffff3300003300333300663300993300cc3300ff332b00332b33332b66332b99332bcc332bff3355003355333355663355993355cc3355ff3380003380333380663380993380cc3380ff33aa0033aa3333aa6633aa9933aacc33aaff33d50033d53333d56633d59933d5cc33d5ff33ff0033ff3333ff6633ff9933ffcc33ffff6600006600336600666600996600cc6600ff662b00662b33662b66662b99662bcc662bff6655006655336655666655996655cc6655ff6680006680336680666680996680cc6680ff66aa0066aa3366aa6666aa9966aacc66aaff66d50066d53366d56666d59966d5cc66d5ff66ff0066ff3366ff6666ff9966ffcc66ffff9900009900339900669900999900cc9900ff992b00992b33992b66992b99992bcc992bff9955009955339955669955999955cc9955ff9980009980339980669980999980cc9980ff99aa0099aa3399aa6699aa9999aacc99aaff99d50099d53399d56699d59999d5cc99d5ff99ff0099ff3399ff6699ff9999ffcc99ffffcc0000cc0033cc0066cc0099cc00cccc00ffcc2b00cc2b33cc2b66cc2b99cc2bcccc2bffcc5500cc5533cc5566cc5599cc55cccc55ffcc8000cc8033cc8066cc8099cc80cccc80ffccaa00ccaa33ccaa66ccaa99ccaaccccaaffccd500ccd533ccd566ccd599ccd5ccccd5ffccff00ccff33ccff66ccff99ccffccccffffff0000ff0033ff0066ff0099ff00ccff00ffff2b00ff2b33ff2b66ff2b99ff2bccff2bffff5500ff5533ff5566ff5599ff55ccff55ffff8000ff8033ff8066ff8099ff80ccff80ffffaa00ffaa33ffaa66ffaa99ffaaccffaaffffd500ffd533ffd566ffd599ffd5ccffd5ffffff00ffff33ffff66ffff99ffffccffffff00000000000000000000000021f904010000fc002c00000000300024000008ff0001003030d080c1830719dc08c380a043811023463470e3068c8636103ad468a0a1478a3d7cdc3828b1e4c4810c606484c171234b832b1556b47183e6c392040b163c58d3c0cb813b353248c9c006cda30d710a7ce830064c0319111e606963aac28b301ad8d0caa0c78d1e3681e61c0b4085419607285684111461ca8e368ac6ad6903ac999a4b818add6bd029d4867e596284eb11a90d1e60789c591c26a74ea6045f1a98ea74e4c518733dd6acd9f54c8f366d32257383c9a74ebe8f25471e78916651ba371a12b4b1f84cb24c92a00d4b368fe60d0001989a75981633d9a5306273f61d6661983368d24c1a96095332eac394c1c0117427cbe4007e6fff3c8939ccdd3362d04cca34094ea6f7998865d2f41e4d00bd910d4ebd81e90cea812a1c70d41961448706319ad0a78932ca28a8097638e4a79f4f232de4df4d8e0190dc1946b1b720839a10b38c32d010d3e03098bc07d40105bd941c58ff4164c0199ba5211f7bef29a30f3d0c2a43cc27c908936263525135de6a196a88860d611488467a9264320c34f4cc43cf3eca24739b2423ad8856558feda5170036c0b05875d525438f96c3e8e3a689c30883cc750038f5520c29a1c49641c19d26d00d8b59978990fa28334f32c86032cc6e5ace390f347b4ee693010d74749141640ae89701e59d8149738a2eaacf75c81cbadb3cf33c334c3eca583655470216ff55949d6fbd25d073c96082c924050e834632cae4b326329708e3493e87023b8c531911d55a51068d0495a4148561c33061b8f1e442efd133aa30420a034324ba469289b4b4c666546ce1593a2d0051a2b1e40d93a02189bc0bd91049189720834c3e006022a7ae16bd1b5e5160653452b3fa0110c6303412338c269848726f18fd9d71c9c6c844826832f90c63805940c15697c2714dcad240c9a0918932230e23498a370c838c3097408233b8d609a30c1a11c1905cbee20dd6c04f30647246760bc67cef33e1623227c815032b4944628cf41c1a04ca359464026582c60d632c2322836e48f2dc30cf6879db24312433c90df7e584890df2167837b44461ff2a10266cc540cc26088a418caecf35969ecb318411034e31d04853d7b16535a9df1081428ce60194880969f25247c9246224c7167ea637b790ba0a5164da4d38e0701f003a2a43dd19f351f2c624385494de98ac85d75c7815411b958c1ab69b9318f464228326946832461a38a457d10d8fe70591457f66341742003080e7c2df4194468863f47e7dd6154d8461b4281be59380d342c55597371013e1010ca051e0f5806a9f9f767294e28de4235bb9546b7ec39d85d94024d76bce93c616832e2504253d00cb4162b2417791042a020a204dc6c6b509aa2f5a1bfc0a513e322d8f843065d18a8debbe424279f5c07fbd734a4316d8c24b518401fca348ca2a30229e10bee606f842e2d8aa87bda8442b2595cac8d1be06c58e30ab23f5ab49087be0247c25f1060101003b,
    '紫陽花',
    'ユーザ名'
);

PHPで保存

共通(フォーム部分)

<form method="POST" action="./save.php" enctype="multipart/form-data">
    <input type="file" name="image">
    <input type="text" name="img_name" placeholder="花の名は">
    <input type="text" name="your_name" placeholder="君の名は">
    <input type="submit" value="送信!">
</form>

保存については、save.phpというファイルを新たに作成します。
書き方は2パターン記載します。

Ex.1) file_get_contents を使用する

$dsn  = 'mysql:dbname=image_db;host=localhost;charset=utf8';
$user = 'root';
$pw   = 'password';
$driver_options = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false,
];

//データベースに接続
$pdo = new PDO(
     $dsn,
     $user,
     $pw,
     $driver_options
);

$sql = '
    INSERT INTO
        `image_data` (img, img_name, user_name)
    VALUES
        (:img, :img_name, :user_name)
';

// 画像データ
$img_data = file_get_contents($_FILES['image']['tmp_name']);

// DBに保存
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':img', $img_data);
$stmt->bindValue(':img_name', $_POST['img_name']);
$stmt->bindValue(':user_name', $_POST['your_name']);
$stmt->execute();

Ex.2) fopen を使用する

// DB接続、SQLは Ex.1と同様のため省略

$fp       = fopen($_FILES['image']['tmp_name'], 'rb');
$img_data = fread($fp, filesize($_FILES['image']['tmp_name']));
fclose($fp);

画像を表示する

DBからバイナリデータを取得して、WEB上に表示をさせます。
ここでは2パターン試します。

バイナリデータをbase64エンコードをして画像表示する

この例では、バイナリデータを直接imgタグのソースに書き込むことで画像が表示出来ます。

// DB接続は省略

$sql = 'SELECT * FROM `image_data`';
$stmt = $pdo->query($sql);

// 今回はgif画像なので、image/gifになります
echo '<img src="data:image/gif;base64,' . base64_encode($stmt->fetchAll()[0]['img']) . '>';

phpファイルから画像を表示する。

display.php

// DB接続は省略

// 画像データを取得
$sql = 'SELECT * FROM `image_data` WHERE `id` = :id';
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':id', $_GET['id']);
$stmt->execute();

// 表示
header('Content-type:image/gif');
echo $stmt->fetchAll()[0]['img'];

result.html

<img src="display.php?id=1">

これでDBに直接保存した画像データを表示出来ると思います。
但し、普通はこのやり方はやりません。
サーバー上に画像を保存して、DBにはPATHを保存して表示するのが多いと思います。
このやり方も後々備忘録で残したいと思います。

取りあえず、もしDBから画像データを直接持ってくる案件があった場合は参考になれば幸いです。

PDOの詳細はここを確認してください。

« [VBA]データ型の記号を調べた[MySQL, Codeigniter]DBに絵文字が文字化けしないようにする »

Sponsored Link

コメントする

記事の感想や修正依頼等ありましたら、コメントをお願いいたします