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

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

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

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

PHP

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

アップロード

アップロードは特定のファイルをウェブサーバに送るプロセスのことを指します。

データベース

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

Q&A

解決済

2回答

5271閲覧

【php+mysql】画像をアップロードしてデータベースにサムネイル画像と共に保存して、それを表示したい

awazon042

総合スコア13

MySQL

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

PHP

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

アップロード

アップロードは特定のファイルをウェブサーバに送るプロセスのことを指します。

データベース

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

0グッド

1クリップ

投稿2016/01/27 05:12

現在下記の様に表示していますが、サムネイルをクリックした時に何も表示されません。
それ以外はしっかり機能しています。
画像はデータベースに直接保存しています。
若輩者ですが、ご教授いただければ幸いです
###ソースコード

php

1<?php 2/* HTML特殊文字をエスケープする関数 */ 3function h($str) { 4 return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); 5} 6// XHTMLとしてブラウザに認識させる 7// (IE8以下はサポート対象外w) 8header('Content-Type: text/html; charset=UTF-8'); 9$cast_id = h($_GET['id']); 10$date = (new DateTime('now', new DateTimeZone('Asia/Tokyo')))->format('YmdHis'); 11$name = h($cast_id . "-" . $date); 12try { 13 14 $dsn = 'mysql:dbname=A_datebase;host=A.ne.jp;charset=utf8'; 15 $user = 'A; 16 $password = 'A1234'; 17 $options = array( 18 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // SQL実行失敗時にも例外を投げるようにする 19 PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // デフォルトフェッチモードを連想配列に設定 20 ); 21 // DB接続してPDOインスタンス生成 22 $pdo = new PDO($dsn, $user, $password, $options); 23 /* アップロードがあったとき */ 24 if (isset($_FILES['upfile']['error']) && is_int($_FILES['upfile']['error'])) { 25 26 // バッファリングを開始 27 ob_start(); 28 29 try { 30 31 // $_FILES['upfile']['error'] の値を確認 32 switch ($_FILES['upfile']['error']) { 33 case UPLOAD_ERR_OK: // OK 34 break; 35 case UPLOAD_ERR_NO_FILE: // ファイル未選択 36 throw new RuntimeException('ファイルが選択されていません', 400); 37 case UPLOAD_ERR_INI_SIZE: // php.ini定義の最大サイズ超過 38 case UPLOAD_ERR_FORM_SIZE: // フォーム定義の最大サイズ超過 39 throw new RuntimeException('ファイルサイズが大きすぎます', 400); 40 default: 41 throw new RuntimeException('その他のエラーが発生しました', 500); 42 } 43 44 // $_FILES['upfile']['mime']の値はブラウザ側で偽装可能なので 45 // MIMEタイプを自前でチェックする 46 if (!$info = @getimagesize($_FILES['upfile']['tmp_name'])) { 47 throw new RuntimeException('有効な画像ファイルを指定してください', 400); 48 } 49 if (!in_array($info[2], [IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG], true)) { 50 throw new RuntimeException('未対応の画像形式です', 400); 51 } 52 53 // サムネイルをバッファに出力 54 $create = str_replace('/', 'createfrom', $info['mime']); 55 $output = str_replace('/', '', $info['mime']); 56 if ($info[0] >= $info[1]) { 57 $dst_w = 500; 58 $dst_h = ceil(500 * $info[1] / max($info[0], 1)); 59 } else { 60 $dst_w = ceil(500 * $info[0] / max($info[1], 1)); 61 $dst_h = 500; 62 } 63 if (!$src = @$create($_FILES['upfile']['tmp_name'])) { 64 throw new RuntimeException('画像リソースの生成に失敗しました', 500); 65 } 66 $dst = imagecreatetruecolor($dst_w, $dst_h); 67 imagecopyresampled($dst, $src, 0, 0, 0, 0, $dst_w, $dst_h, $info[0], $info[1]); 68 $output($dst); 69 imagedestroy($src); 70 imagedestroy($dst); 71 72 // INSERT処理 73 74 $stmt = $pdo->prepare('INSERT INTO image(name,cast_id,type,raw_data,thumb_data,date) VALUES(?,?,?,?,?,?)'); 75 $stmt->execute([ 76 $name, 77 $cast_id, 78 $info[2], 79 file_get_contents($_FILES['upfile']['tmp_name']), 80 ob_get_clean(), // バッファからデータを取得してクリア 81 (new DateTime('now', new DateTimeZone('Asia/Tokyo')))->format('Y-m-d H:i:s'), 82 ]); 83 84 $msgs[] = ['green', 'ファイルは正常にアップロードされました']; 85 } catch (RuntimeException $e) { 86 87 while (ob_get_level()) { 88 ob_end_clean(); // バッファをクリア 89 } 90 http_response_code($e instanceof PDOException ? 500 : $e->getCode()); 91 $msgs[] = ['red', $e->getMessage()]; 92 } 93 94 /* ID指定があったとき */ 95 } elseif (isset($_GET['id'])) { 96 97 98 try { 99 100 $stmt = $pdo->prepare('SELECT type, raw_data FROM image WHERE no = ? LIMIT 1'); 101 $stmt->bindValue(1, $_GET['id'], PDO::PARAM_INT); 102 $stmt->execute(); 103 if (!$row = $stmt->fetch()) { 104 throw new RuntimeException('該当する画像は存在しません', 404); 105 } 106 header('X-Content-Type-Options: nosniff'); 107 header('Content-Type: ' . image_type_to_mime_type($row['type'])); 108 echo $row['raw_data']; 109 exit; 110 } catch (RuntimeException $e) { 111 112 http_response_code($e instanceof PDOException ? 500 : $e->getCode()); 113 $msgs[] = ['red', $e->getMessage()]; 114 } 115 } 116 117 // サムネイル一覧取得 118 $rows = $pdo->prepare("SELECT * FROM image WHERE cast_id=? ORDER BY date DESC"); 119 $rows->execute(array($cast_id)); 120} catch (PDOException $e) { 121 122 http_response_code(500); 123 $msgs[] = ['red', $e->getMessage()]; 124} 125?>

html

1 <?php if (!empty($rows)): ?> 2 <legend>サムネイル一覧(クリックすると原寸大表示)</legend> 3 <div class="thumnail_table"> 4 5 <?php foreach ($rows as $i => $row): ?> 6 <table class="cast_photo_table"> 7 <tbody> 8 <tr> 9 <td colspan="2"> 10 <?= 11 sprintf( 12 '<a href="?no=%d"><img src="data:%s;base64,%s" alt="%s" width="200px"/></a>', $row['no'], image_type_to_mime_type($row['type']), base64_encode($row['thumb_data']), h($row['name']) 13 ) 14 ?></td> 15 </tr> 16 <tr><th>ファイル名:</th><td><?= h($row['name']) ?></td></tr> 17 <tr><th>日付:</th><td><?= h($row['date']) ?></td></tr> 18 <tr><td colspan="2"><span class="delete"><a href="delete_photo.php?no=<?= h($row['no']) ?>">削除する</a></span></td><tr> 19 </tbody> 20 </table> 21 <?php endforeach; ?> 22 </div> 23 <?php endif; ?>

###補足情報(言語/FW/ツール等のバージョンなど)

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

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

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

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

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

usk

2016/01/27 06:55 編集

追加・修正依頼を記載しましたが、表示内容が汚くなったので、コメント欄にて再掲載します。
guest

回答2

0

aタグはリンクタグなので、その先に原寸表示用のページを作る必要があるのではないかと思います。
row["no"]は数字のようなので、おそらくidか何かだと思いますが、当然番号にリンクしても何も起こりません。
photo.phpか何かを作り、そちらにGETでidを飛ばして、受け取ったIDからバイナリデータを取得、表示という作業が必要なように思います。

表示のさせ方については以下が使えそうかな?と思います。
画像をデータベースに保存、ブラウザで表示する

単純にリンクだけで見れるようにしたいのであれば、DBでなくどこかに直接元画像を保存し、そのパスをDBに格納してaタグの飛び先にしてあげれば大丈夫です。

投稿2016/01/27 07:32

編集2016/01/27 07:37
ao_love

総合スコア441

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

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

0

ベストアンサー

(追加・修正依頼です)

それ以外はしっかり機能しています。

サムネイルが表示されていないということは、どこかに問題が隠れているはずです。
何がしっかりと機能しているか、もう少し明確にお伝えいただけないでしょうか。

  • DB にデータは保存されているかどうか
  • ID を元にDBからデータを取得するところは正しく動いているかどうか

(PHP上で、IDからデータが取得できたかどうか)

  • HTML に DB から取得した画像データ base64 エンコード済みの文字列は設定されているかどうか
  • base64エンコードされた画像のデータはブラウザのURLに入力した場合、画像が表示されるかどうか

このあたりを確認してみて、もう少し問題内容を詳細化することは可能でしょうか。

参考URL
http://blue-ham-cake1024.hatenablog.com/entry/2013/02/09/Base64%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%89%E3%81%95%E3%82%8C%E3%81%9F%E7%94%BB%E5%83%8F%E3%82%92%E3%83%87%E3%82%B3%E3%83%BC%E3%83%89%E3%81%97%E3%81%A6%E9%96%B2%E8%A6%A7%E3%81%99

投稿2016/01/27 06:55

編集2016/01/27 06:58
usk

総合スコア397

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

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

awazon042

2016/01/27 07:09

すいません、質問の文章がおかしかったのかもしれません。 サムネイルは表示されているのですが、サムネイルをクリックした後の挙動がおかしいということです。 <a href="?no=%d"><img src="data:%s;base64,%s" alt="%s" width="200px"/></a>', $row['no'], image_type_to_mime_type($row['type']), base64_encode($row['thumb_data']), h($row['name']) の<a href="?no=%d">ここの部分だと思います!
usk

2016/01/27 08:43 編集

PHP のコードの $_GET["id"] に入るようにしたいのであれば、href部分 の Key の指定は "no" ではなく "id" のにする必要がある・・・ということじゃないかな。 × href="?no=%d" ○ href="?id=%d" 補足事項: > header('Content-Type: text/html; charset=UTF-8'); この一文をすべての処理の最初に設定しているので、どうあってもブラウザはサーバーからの返却値を ”text/html" と解釈してしまいます。 HTMLを返却する場合のみ、上記ヘッダをセットするようにして見てください。
awazon042

2016/01/27 08:45

× href="?no=%d" ○ href="?id=%d" この方法で出来ました! 本当にありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問