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

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

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

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

解決済

1回答

7500閲覧

データベースに格納した画像が表示されない

mi_

総合スコア80

PHP

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

0グッド

0クリップ

投稿2016/11/11 09:34

編集2016/11/12 05:06

PHP逆引きレシピ第2版のイメージデータを格納という課題を行っています。
データベースに画像を保存して、その画像を確認するまでの内容です。
テーブル名など、こちらが作りたいものにあわせて変えていますが、基本的にはサンプルコードのままつくっているつもりです。

イメージ説明

データベースへの接続エラー等、たくさん出てしまったエラーもでなくなったのですが、
最終的に、画像が表示されるべき画面で、ブラウザ(クローム)の左上に小さな四角の枠だけ表示され、4,5時間行き詰っています。

イメージ説明

右クリックでページのソースコードをみようにも、ソースコードもクリックできません。フリーズしているんでしょうか?

大変恐れ入りますが、下記をご覧いただいて原因をつきとめていただけたらと思います。

XAMPPで、ApacheとMySQLを動かしています。

データベース名 blogdb
テーブル名 image_t
id int(11) NUllいいえ AUTO_INCREMENT プライマリ
image mediumbblob NULLいいえ

image-upload.php

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>イメージデータを格納したい</title> </head> <body> <div> <?php require_once '/lib/h.php'; $max_size=4*1024*1024; //最大4MB $file_uploaded = false; //ファイルがアップロードされたとき、画像かどうかの確認 if (isset($_FILES['image'])){ //アップロードされた画像のチェックを行う if(! check_image()){ echo '<p>アップロードされたファイルはJPEG画像でないか、または処理できない画像です。</P>'; //画像のファイルサイズのチェックを行う } elseif ($_FILES['image']['size'] > $max_size){ echo '<p>ファイルサイズが4MB以下のものをアップロードしてください。</p>'; //画像ファイルをfopen()関数で開く } elseif (! $file = fopen($_FILES['image']['tmp_name'],'rb')){ echo '<p>画像を開けませんでした</p>'; } else { //画像ファイルをfread()関数で読み込む $image = fread($file,$_FILES['image']['size']); fclose($file); if (! $image){ echo '<p>画像を読み込めませんでした</p>'; } else { $file_uploaded = true; } } } //画像が正常にアップロードされていれば、データベースに追加する。 if ($file_uploaded == true){ //データベース設定を読み込む require_once __DIR__.'/database_conf.php'; try{ //MySQLデータベースに接続する $db = new PDO($dsn,$dbUser,$dbPass); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //SQL文を準備する $sql = 'INSERT INTO image_t(image) VALUES(:image)'; $prepare =$db->prepare($sql); //SQL文のプレースホルダに値をバインドしてクエリを実行する。 $prepare->bindValue(':image',$image,PDO::PARAM_LOB); $prepare->execute(); //追加したレコードのIDを取得する $id = $db->lastInsertId(); //追加に成功した場合、画像表示ページへのリンクを表示する echo '<p><a href="upload_image.php?id=' .h($id).'">アップロードした画像を表示する</a></p>'; //エラーが発生した場合、PDOException例外がスローされるのでキャッチする。 } catch (PDOException $e) { echo 'エラーが発生しました。内容:'.h($e->getMessage()); } } //画像形式をチェックし、画像かどうかの判定を行う関数 function check_image() { $tmp_name = $_FILES['image']['tmp_name']; //画像がアップロードされたふぁいるかどうかをチェックする。 if (! is_uploaded_file($tmp_name)){ return false; } //画像の種類がJPEGかをfinfoクラスで確認する。 $finfo = new finfo(FILEINFO_MIME_TYPE); $type = $finfo->file($tmp_name); if ($type !== 'image/jpeg'){ return false; } return true; } ?> <p>JPEG画像のみアップロードできます(4MBまで)</p> <form method="post" action="image_upload.php" enctype="multipart/form-data"> <input type="hidden" name="MAX_FILE_SIZE" value ="<?php echo h($max_size); ?>"> <input type="file" name="image" value=""> <input type="submit" name="submit"> </form> </div> </body> </html>

upload-image.php

<?php require_once __DIR__.'/database_conf.php'; require_once __DIR__.'/lib/h.php'; //ユーザーが入力したIDを検証する if(isset($_GET['id']) && ctype_digit($_GET['id'])){ $id = (int) $_GET['id']; } else { exit('IDが不正です。'); } try { //MySQLデータベースに接続する $db = new PDO($dsn,$dbUser,$dbPass); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //SQL文を準備する $sql = 'SELECT image FROM image_t WHERE id = :id'; $prepare = $db->prepare($sql); //SQL文のプレースホルダに値をバインドしてクエリを実行する。 $prepare->bindValue(':id',$id,PDO::PARAM_INT); $prepare->execute(); //結果をカラム名をキーとした連想配列で取得 $result = $prepare->fetch(PDO::FETCH_ASSOC); if ($result && isset($result['image'])){ header("Content-Type:image/jpeg"); //Internet ExplorerがContent-Typeヘッダーを無視しないように headder('X-Content-Type-Options:nosniff'); echo $result['image']; } //エラーが発生した場合、PDOException例外がスローされるのでキャッチする。 } catch (PDOException $e) { echo 'エラーが発生しました。内容:'.h($e->getMessage()); }

h.php

<?php function h($var) { if (is_array($var)){ return array_map('h',$var); } else { return htmlspecialchars($var,ENT_QUOTES,'UTF-8'); } }

database_conf.php

<?php //データベース設定 $dbServer = 'localhost'; $dbUser = 'staff'; $dbPass = 'password'; $dbName = 'blogdb'; $dsn= "mysql:host={$dbServer};dbname={$dbName};charset=utf8";

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

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

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

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

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

kei344

2016/11/11 15:05

コードはそれぞれコードブロックで囲んでいただけませんか? ```(バッククオート3つ)で囲み、前後に改行をいれるか、コードを選択して「<code>」ボタンを押すとコードブロックになります。
mi_

2016/11/12 05:07

ご指摘ありがとうございました。編集させていただきました。
kei344

2016/11/12 08:06

「upload_image.php?id=(idの値)」にブラウザでアクセスしてみてください。エラーがでていませんか?
mi_

2016/11/12 10:58

ありがとうございます。何度もアップロードしたのでIDがだいぶ進みましたが、現在http://localhost/blog/upload_image.php?id=29などに自動的に移行します。その時の画面が、左上に小さな□になっています。なぜか右クリックでソースが見れません。
mi_

2016/11/12 11:05

chromeではなく、Internetexplorerで動作させたところ、ソースコードに<br /> <b>Fatal error</b>: Call to undefined function headder() in <b>C:\xampp\htdocs\blog\upload_image.php</b> on line <b>32</b><br />の表示がありましたので、headerと訂正しました。Internetexplorerでも、小さな×の表示になり、ソースも見れなくなりました。
kei344

2016/11/12 11:23

ファイルとしてダウンロードして、テキストエディタなどで読めませんか?
popobot

2016/11/12 22:32 編集

手元で動かしてみたところheadderをheaderに直したら表示されましたよ!? ブラウザはChormeで確認しました。headderを直す前は質問文にある四角が表示されていました。デベロッパーツールのNetworkでレスポンスデータを見るとどうなっていますか? kei344さんのファイルとしてダウンロードする方法でも確認内容は同じだと思いますけど。
popobot

2016/11/12 22:35

後、一旦画像が正しく保存されているか、MySQL側でselect * from image_t where id = 1;とか実行したら画像のバイナリデータが表示されますか?
mi_

2016/11/14 05:35

MySQLでダウンロードすると、image_t-image(3).binなどでダウンロードされ、拡張子を.jpgに変えると画像が表示されます。
mi_

2016/11/14 06:04

icchiiさんの意見を参考に、ここにコピぺしたコードに入れ替えて、headerに書き換えたところ急に表示されるようになりました。大変お騒がせしました。本当にありがとうございました。
guest

回答1

0

ベストアンサー

データベースへの格納のときは、イメージデータをBindParam()でラージオブジェクトとしてバインドしていますね。ですからデータベースから取り出すときも、ラージオブジェクトとして扱わなければいけないです (ちなみにPDOでの「ラージオブジェクト」は単に「大きいもの」というだけではなく、バイナリデータも含みます)。

PHPマニュアルにある例をまねして、次のようにすればLOBを取得して出力できるはずです。

lang

1//SQL文を準備する 2 $sql = 'SELECT image FROM image_t WHERE id = :id'; 3 $prepare = $db->prepare($sql); 4 5//SQL文のプレースホルダに値をバインドしてクエリを実行する。 6 $prepare->bindValue(':id',$id,PDO::PARAM_INT); 7 $prepare->execute(); 8 9// (ここまでは元のコードと同じ) 10 11//変数に列をバインドして値を取得する。 12 $prepare->bindColumn(1, $lob, PDO::PARAM_LOB); 13 $prepare->fetch(PDO::FETCH_BOUND); 14 15//出力する ($lobはデータそのものではなくストリームオブジェクトであることに注意) 16 header("Content-Type: image/jpeg"); 17 fpassthru($lob); 18

なお、これでうまくいかないときは、PHPとMySQLサーバのバージョンを知らせてください。古めのバージョンのPHPではLOBまわりの処理にバグがあるようですので。

投稿2016/11/13 02:22

編集2016/11/13 04:42
ikedas

総合スコア4335

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問