PHPとMySQLでの画像のバイナリ保存・表示方法【現役エンジニアが解説】

PROGRAM

今回は、PHPとMySQLでの画像のバイナリ保存・表示方法について、MySQL側とPHP側に分け、簡単に解説していきます。

MySQL側の準備

まず、画像を保存するためにMySQLのデータベースに画像保存用のテーブルを作ります。

CREATE TABLE images(
    image_no INT AUTO_INCREMENT,
    image_mime VARCHAR(50),
    image_data MEDIUMBLOB,
    PRIMARY KEY(image_no)
);

バイナリで保存するため、画像データを保存するカラムはBLOB型とし、容量の多少大きいMEDIUMBLOB型にします。

また、バイナリで保存すると、元の画像を再現する際に画像の形式が必要となるため、MIMEタイプを保存するカラムも用意します。

PHP側の保存処理

PHPから先程作成したMySQLのテーブルに画像をバイナリで保存するサンプルコードは以下のとおりです。

$fp = fopen($_FILES['name']["tmp_name"], "rb"); // 'name'はフォームデータのname属性
$image_data = fread($fp, filesize($_FILES['name']["tmp_name"])); // 'name'はフォームデータのname属性
$image_mime = 'image/jpeg'; // 必要に応じて分岐処理等にする
fclose($fp);

$pdo = new PDO("mysql:host={host};dbname={dbname}", "{user}", "{password}");
$sql = "INSERT INTO TBL_DISASTER_IMG_FILE(image_mime, image_data) VALUES(:image_mime, :image_data)";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':image_mime', $image_mime);
$stmt->bindValue(':image_data', $image_data);
$stmt->execute();

上記のコードでは、HTMLのフォームデータからjpeg形式の画像データが送られてくることを想定しています。

jpeg形式以外の画像も取り扱いたい場合には、MIMEタイプは分岐処理等で適切に判断して保存するようにします。

PHP側の表示処理

PHPからMySQLに保存されたバイナリの画像データを表示するサンプルコードは以下のとおりです。

$pdo = new PDO("mysql:host={host};dbname={dbname}", "{user}", "{password}");
$sql = "SELECT IMG_MIME, IMG_DATA FROM images WHERE image_no = :image_no";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':image_no', "{image_no}", PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
$image = $result[0];
header( "Content-Type: ".$image['image_mime'] );
echo $image['image_data'];

バイナリデータのため、基本的にはそのまま出力すれば、ブラウザ側で画像を表示することができます。

ただし、ブラウザ側も画像の形式がわからないと表示ができないため、レスポンスヘッダのContent-TypeにMIMEタイプを記載します。