質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

5591閲覧

DBに保存した画像を連続して表示したい。

jesushill

総合スコア37

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

3クリップ

投稿2016/06/05 07:38

編集2016/06/05 07:41

PHPを勉強している者です。

###行いたいこと
DBに保存している画像を連続して表示させたいのですが、
一枚しか表示されず、困っています。
うまく表示するにはどのように行えばいいのでしょうか。
ループ自体は問題ないようなので、表示方法に問題があるのでは
と考えています。
どなたかご教授頂ける方いらっしゃりましたら宜しくお願い致します。
※画像のDB保存形式は 名前:IMG データ型:mediumblob
で保存しています。

lang

1<?php 2// DB接続 3try { 4 $pdo = new PDO('mysql:dbname=share_note;charset=utf8;host=localhost','root',''); 5} catch (PDOException $e) { 6 exit('データベースに接続出来ませんでした'.$e->getMessage()); 7} 8 9$stmt = $pdo->prepare("SELECT IMG FROM IMAGES"); 10$status = $stmt->execute(); 11 12if ($status == false) { 13 $error = $stmt->errorInfo(); 14 exit("ErrorQuery:".$error[2]); 15}else { 16 while($result = $stmt->fetch(PDO::FETCH_ASSOC)){ 17 header("Content-Type: image/jpeg"); 18 echo $result["IMG"]; 19 } 20} 21 22?> 23 24

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

PHP以前に,HTTPの仕組みをわかっていなければこのコードがやっていることも理解できないと思います.まず以下を一読してください.とくに今回Content-Typeヘッダは重要です.

前提として,PHPはデフォルトでは以下のようなContent-Typeヘッダを出すようになっています.

Content-Type: text/html

つまり特に設定しなければ,PHPが送出するデータはHTMLとして取り扱われるということです.ここでheader関数の第2引数をtrue(デフォルトではこれ)にして使うと,規定されている同一名称のヘッダを上書きすることができます.ご提示のコードではJPEG画像として表示させるためにimage/jpegとされていますよね.

注意して欲しいのは,HTTP通信では原則的に1リクエストにつき1つのファイルしか返せないということです.では,画像を含むHTMLはどうやって表示されているのでしょうか?答えは,取得したいデータごとにWebブラウザが個別にHTTPリクエストを実行している,です.例えば http://example.com/index.php が返すコンテンツに

html

1<img src="images/logo.png">

というHTMLタグが含まれていれば,

1. http://example.com/index.php
2. http://example.com/images/logo.png

というように続けてHTTPリクエストが行われます.

さて,ここまで説明したことを踏まえると,やっていることがおかしい,ということに気づけるんじゃないでしょうか.そこでどうすべきかという話になりますが,方法は2つあります.

PHPによるレスポンスを単一の画像ファイルにする

単一の画像を返すだけのPHPスクリプトを書いておいて,

html

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

のような感じでimg要素のsrc属性にPHPスクリプトを指定する,という方法です.但し,この方法だとSELECTを何回も実行する必要があり,効率を考えるとあまり良くない方法になってしまうと思います.

データURIスキームにしてHTMLに埋め込む

実は,HTML中に画像データをそのまま埋め込んでしまう方法も用意されているんです.

但し画像の生データをそのままでは埋め込めないので,BASE64エンコードを通じてアルファベットと記号の羅列だけに変換します.画像サイズが極端に大きくなければこれで捌けると思います.

html

1<img src="data:image/jpeg;base64,<?=base64_encode(画像データ)?>">

【実装例】

html

1<?php 2 3try { 4 5 // 接続 6 $pdo = new PDO('mysql:dbname=share_note;charset=utf8;host=localhost', 'root', '', [ 7 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // SQL実行に失敗した場合にもPDOExceptionを投げる 8 ]); 9 10 // 画像データを1次元配列として取得 11 // 取り扱いやすいが,画像サイズ総量が大きい場合にメモリがつらい 12 // $images = $pdo->query('SELECT img FROM images')->fetchAll(PDO::FETCH_COLUMN, 0); 13 14 // 画像データを取り出せるイテレータとして取得 15 // やや取り扱いにくいが,画像サイズ総量が大きくても余裕 16 $images = $pdo->query('SELECT img FROM images'); 17 $images->setFetchMode(PDO::FETCH_COLUMN, 0); 18 19} catch (PDOException $e) { 20 21 // 500 Internal Server Errorでテキストとしてエラーメッセージを表示 22 header('Content-Type: text/plain; charset=UTF-8', true, 500); 23 exit($e->getMessage()); 24 25} 26 27// HTMLとして表示 (文字コードもここで指定するために上書きする) 28header('Content-Type: text/html; charset=UTF-8'); 29 30?> 31<!DOCTYPE html> 32<title>JPEG画像一覧</title> 33<style> 34 img { float: left; } 35</style> 36<h1>JPEG画像一覧</h1> 37<?php foreach ($images as $i => $img): ?> 38<img src="data:image/jpeg;base64,<?=base64_enode($img)?>" alt="画像<?=$i+1?>"> 39<?php endforeach; ?>

投稿2016/06/05 08:19

編集2016/06/05 08:37
mpyw

総合スコア5223

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mpyw

2016/06/05 08:32

そもそもの設計として,取り扱いやすさを考えると「ファイル名のみをデータベースに格納し,データはファイルシステムの中に置いておく」としたほうがいいかもしれませんね.
jesushill

2016/06/05 10:05

回答頂きましてありがとうございます。HTTP通信は原則 1リクエストにつき、1ファイル(私の例で言うとjpgファイル?)しか返せなかったのは知りませんでした。 mpywさんの仰る通り、DBにはファイル名をつけるべきなんですが、今回は出来ないような条件でアプリを作ってみたいと考えておりました。 最後から二番目の行は「base64_enode($img)?」とありますが、enode→encodeですね。 丁寧に回答して頂きましてありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問