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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

Q&A

解決済

3回答

11030閲覧

MYSQLにバイナリで保存した画像を表示する方法

SugiuraY

総合スコア317

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

1グッド

1クリップ

投稿2017/02/05 02:44

編集2017/02/05 04:03

お世話になります。
現在、ユーザーからinput="file"で取得したデータをMYSQLにバイナリで保存し、このデータを出力するコードを作成しています。MYSQLにはバイナリデータ(BLOB形式)とMIME(image/jpeg)が格納されており、これをimg.phpで取得して、headerに送信するとともに表示しております。なお、バイナリデータはユーザから formのinput="file"から取得しております。
一方で、output.phpはこれをimg srcに出力し画像を表示させようとしております。

①しかしながらこの結果、HTML上では定番の小さな写真が割れたようなアイコンが表示され意図したimg描画ができていません。どなたか、

なお、バイナリにまだまだ不案内なため、適切か否かはわからないのですが例えば以下のような文字列になっているのですが、一般的な文字化けの状態に見えるのですが、これが原因なのでしょうか?
�a��hfe�+��#�Qn�ǘ8_ڗ]�����[��(˻�#;p�X~_u?J��BrQ��z3��/�\

②また、phpでユーザーから画像とのファイルを取得する場合、ファイルを取得、保存し、それを出力する方法として、より一般的な方法があれば
ご教示いただければ幸いです。

PHP

1img.php 2 3try { 4$pdo = new PDO($dsn, $user, $password,array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET CHARACTER SET `utf8`")); 5$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 6}catch (PDOException $e){ 7 var_dump($e->getMessage()); 8 } 9 10 try { 11 $stmt=$pdo->query("SELECT picture,mime FROM a_inputDB"); 12$result=$stmt->fetchall(PDO::FETCH_NUM); 13 14}catch(PDOException $e){ 15echo "失敗しました。" . $e->getMessage(); 16} 17 18header("Content-type:".$result[0][1]);//$result[0][1]=image/jpeg 19echo $result[0][0];//$result[0][0]="���[��(˻�#;p�X~_u....割愛 20 ?> 21 22output.php 23 <?php 24echo '<img src="img.php" />'; 25?> 26

PHP

1input.php 2<form class="form" action="" method="post" enctype="multipart/form-data"> 3<div> 4<label>画像を投稿する</label><br /> 5<input type="hidden" name="MAX_FILE_SIZE" value="300000" /> 6<input name="2_picture" type="file" size="35" value="" /> 7</div> 8 9<?php 10// バイナリ 11 $fp = fopen($_FILES["2_picture"]["tmp_name"], "rb"); 12 $imgdat = fread($fp, filesize($_FILES["2_picture"]["tmp_name"])); 13 fclose($fp); 14 $imgdat = addslashes($imgdat); 15 16 // 拡張子 17 $dat = pathinfo($_FILES["2_picture"]["name"]); 18 $extension = $dat['extension']; 19 20 // MIME 21 if ( $extension == "jpg" || $extension == "jpeg" ) $mime = "image/jpeg"; 22 else if( $extension == "gif" ) $mime = "image/gif"; 23 else if ( $extension == "png" ) $mime = "image/png"; 24?> 25 26$dsn = 'mysql:dbname=XXX;host=XXXX'; 27$user = 'XXXX'; 28$password = 'XXXXX'; 29 30try { 31$pdo = new PDO($dsn, $user, $password); 32$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 33}catch (PDOException $e){ 34 var_dump($e->getMessage()); 35 } 36 37 try { 38$pdo->beginTransaction(); 39$stmt=$pdo->prepare("INSERT INTO a_inputDB (picture,picturemim) 40 VALUES(:picture,:picturemime"); 41$stmt->bindValue(':picture',$imgdat,PDO::PARAM_STR); 42$stmt->bindValue(':picturemime',$mime,PDO::PARAM_STR); 43$stmt->execute(); 44$pdo->commit(); 45 46}catch(PDOException $e){ 47$pdo->rollBack(); 48echo "失敗しました。" . $e->getMessage(); 49}
yodel👍を押しています

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

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

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

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

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

guest

回答3

0

ベストアンサー

一応、こちらで試してみてアップロード及び表示はできました。
動作したコードを載せます。
違うところといえば、ファイルからバイナリーデータを取得するのにはfile_get_contents()を使用しているのと、MIMETYPEを取得するのにはfinfo_open()/finfo_file()を使用しているところくらいです。

img.php

php

1<?php 2 try { 3 $pdo = new PDO('mysql:host=localhost;dbname=image_db;charset=utf8', 'test_user', 'pass'); 4 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 5 $stmt = $pdo->query("SELECT picture, picturemime FROM a_inputdb"); 6 $result = $stmt->fetchall(PDO::FETCH_ASSOC); 7 header('content-type:'. $result[0]['picturemime']); 8 echo $result[0]['picture']; 9 }catch(PDOException $e){ 10 echo "失敗しました。" . $e->getMessage(); 11 } 12?>

upload.php

php

1<?php 2if(isset($_FILES["2_picture"]["tmp_name"])){ 3 try { 4 $pdo = new PDO('mysql:host=localhost;dbname=image_db;charset=utf8', 'test_user', 'pass'); 5 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 6 $upFile = $_FILES["2_picture"]["tmp_name"]; 7 $upFileData = file_get_contents($upFile); 8 $finfo = finfo_open(FILEINFO_MIME_TYPE); 9 $mime_type = finfo_file($finfo, $upFile); 10 $stmt=$pdo->prepare("INSERT INTO a_inputDB(picture, picturemime) values (:img, :mime)"); 11 $stmt->bindValue(':img', $upFileData, PDO::PARAM_LOB); 12 $stmt->bindValue(':mime', $mime_type, PDO::PARAM_STR); 13 $stmt->execute(); 14 }catch(PDOException $e){ 15 echo "失敗しました。" . $e->getMessage(); 16 } 17} 18?> 19<!DOCTYPE html> 20<html> 21 <head> 22 <meta charset="utf-8"> 23 </head> 24 <body> 25 <form method="POST" action="image_upload.php" enctype="multipart/form-data"> 26 <input type="file" name="2_picture" /><br /> 27 <input type="submit" value="送信" /> 28 </form> 29 </body> 30</html>

投稿2017/02/05 07:48

turbgraphics200

総合スコア4267

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

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

SugiuraY

2017/02/05 11:34

ご回答ありがとうございます。file_get_contentsでうまく取得し、表示することができました! 誠にありがとうございます。MIMETYPEはうまく取得できていたので["tmp_name"])をうまく読み込めていなかったのかと思いますが、何れにしても、本当に助かりました。 最後までお付き合いをいただき、改めて御礼を申し上げます。 よろしくお願い申し上げます。
guest

0

画像保存時のバイナリーデータのところでPDO::PARAM_STRを設定してますが、PDO::PARAM_LOBとすべきではないでしょうか?

投稿2017/02/05 04:11

turbgraphics200

総合スコア4267

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

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

SugiuraY

2017/02/05 05:40

ご指摘の点は、おっしゃるとおりでした。修正し、casheもクリアしましたが、表示はされません。。MYSQL側のエンゴード等の問題なのか、、(全てutf-8にはしておりますが)。。
guest

0

1MB以上の画像ファイルってことはないですか?
参考

投稿2017/02/05 03:15

turbgraphics200

総合スコア4267

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

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

SugiuraY

2017/02/05 03:22

ご返信ありがとうございます。サイズは8KBです。念のためにLONGBROB型でMYSQLで保存もしてみたが同じ結果となりました。
turbgraphics200

2017/02/05 03:27 編集

そうですか。ちなみに、devToolsでNetworkのところ開いて、ページをリロードしてみて、image.phpのレスポンスヘッダがどうなっているか(特にcontent-type)を見てみてください。
SugiuraY

2017/02/05 03:30

加えてとなりますが、もう一つきになる点として、諸々参考にしているサイトではMYSQLに格納する際に $result = mysqli_query( $db_link, 'INSERT INTO img_table (img_col) VALUES ( "'.$img_binary.'" )'); のようにVAUESの変数の前後にドット(連結演算子?)をつけていましたした。 私はPDOを使用しているので INSERT INTO db (imgcol,mime) VALUES (:imgcol,:mime);のようにユーザのfileを格納しております。実はこの参考にしているコードの変数前後のドットの意味がわからなかったのですが、ファイル自体はカラムに格納できたのであまり気にしておりませんでした。
turbgraphics200

2017/02/05 03:32 編集

ええ、preparedを使用するほうが正しいです。
SugiuraY

2017/02/05 03:44

レスポンスヘッダは以下の通りです。 Connection:Keep-Alive Content-Type:image/jpeg Date:Sun, 05 Feb 2017 03:43:47 GMT Keep-Alive:timeout=5, max=100 Server:Apache Transfer-Encoding:chunked X-Powered-By:PHP/5.6.21
turbgraphics200

2017/02/05 03:48

あと、PDO接続のところでarray(PDO::MYSQL_ATTR_INIT_COMMAND => "SET CHARACTER SET `utf8`")を設定してますがこれを外して試してみてください。
turbgraphics200

2017/02/05 03:52

あ、懸賞の際には念のためブラウザー側のキャッシュをクリアしてから行ってください。
SugiuraY

2017/02/05 03:56

ご指摘のCHARCTER SETを外してみましたが、やはり依然として画像が適切に表示されない(破れた写真のアイコン)のままのようです。 MYSQLへの格納のコードについて、念のために上記質問に加筆させていただきます。
SugiuraY

2017/02/05 04:05

はい、casheをクリアして実行をしてみましたが、同様の結果です。 よろしくお願い申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問