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

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

ただいまの
回答率

89.20%

PHP,MySQL 画像表示されない!(mysqlでデータが文字化け・ブラウザに画像表示されない)

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 903

mango

score 17

目指してること

画像投稿サイトを作っています。
phpでアップロードした画像をmysqlに格納して、ランキングや新着など用途別に引っ張ってこれるようにしたいです。

問題点

画像データをfile_get_contentsした後に、DBのlongblob型のカラムに格納すると、select * from posts で取り出した際に文字化けしてしまいます。
また、ブラウザに表示される画像も壊れてしまい、表示されません。
原因を特定して、解決したいです。

やってみたこと

MySQLのcharacter_setの確認。
→utf8mb4になっていた。

ソースコード

posts_table

+-------------+----------+------+-----+---------+-------------------+
| Field       | Type     | Null | Key | Default | Extra             |
+-------------+----------+------+-----+---------+-------------------+
| id          | int(11)  | NO   | PRI | NULL    | auto_increment    |
| file_name   | text     | NO   |     | NULL    |                   |
| extension   | text     | NO   |     | NULL    |                   |
| likes_count | int(11)  | YES  |     | 0       | DEFAULT_GENERATED |
| raw_data    | longblob | NO   |     | NULL    |                   |
| created     | datetime | YES  |     | NULL    |                   |
| modified    | datetime | YES  |     | NULL    |                   |
+-------------+----------+------+-----+---------+-------------------+

ImageUploader.php → 画像データをDBにアップロードする際の処理

$raw_data = file_get_contents($_FILES['image']['tmp_name']);

$date = getdate();
$file_name = $_FILES["image"]["tmp_name"].$date["year"].$date["mon"].$date["mday"].$date["hours"].$date["minutes"].$date["seconds"];
$file_name = hash("sha256", $file_name);

$sql = "INSERT INTO posts(file_name, extension, raw_data) VALUES (:file_name, :extension, :raw_data);";
$stmt = $pdo->prepare($sql);
$stmt -> bindValue(":file_name",$file_name, \PDO::PARAM_STR);
$stmt -> bindValue(":extension",$ext, \PDO::PARAM_STR);
$stmt -> bindValue(":raw_data",$raw_data, \PDO::PARAM_STR);
$stmt -> execute();

index.php → 表示画面

$sql = "SELECT * FROM posts ORDER BY id;";
$stmt = $pdo->prepare($sql);
$stmt -> execute();
while ($row = $stmt -> fetch(\PDO::FETCH_ASSOC)){
 echo ($row["id"]."<br/>");
 $target = $row["file_name"];
 echo ("<img src='import_media.php?target=$target'>");
 echo ("<br/><br/>");
}

impor_media.php → DBから画像データを取り出す処理

if(isset($_GET["target"]) && $_GET["target"] !== ""){
    $target = $_GET["target"];
}else{
    header("Location: mypage.php");
}

$MIMETypes = array(
    'png' => 'image/png',
    'jpeg' => 'image/jpeg',
    'gif' => 'image/gif',
);

try {
   $dsn = "mysql:dbhost=localhost;dbname=dotinstall_sns_php";
   $username = "dbuser";
   $password = "mu4uJsif*";
   $pdo = new \PDO($dsn, $username, $password);
   $sql = "SELECT * FROM posts WHERE file_name = :target;";
   $stmt = $pdo->prepare($sql);
   $stmt -> bindValue(":target", $target, \PDO::PARAM_STR);
   $stmt -> execute();
   $row = $stmt -> fetch(\PDO::FETCH_ASSOC);
   header("Content-Type: ".$MIMETypes[$row["extension"]]);
   echo ($row["raw_data"]);
}
catch (\PDOException $e) {
   echo("<p>500 Inertnal Server Error</p>");
   exit($e->getMessage());
}

参考サイト

https://qiita.com/NULLchar/items/7bdc6685be0aa909e8fe

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+2

teratailでも何度も出てきてるけど画像をDBに入れてはいけない。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/27 11:38

    そうなんですね!
    では、どうすればいいのですか?

    キャンセル

  • 2018/11/27 12:13

    ディレクトリなり、外部ストレージ(AWSならS3とか)に保存しましょう。
    DBに入れるのはそのファイルパス。

    キャンセル

checkベストアンサー

0

とりあえずラージオブジェクト (LOB) を利用してみてはいかがでしょうか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 89.20%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる
  • トップ
  • PHPに関する質問
  • PHP,MySQL 画像表示されない!(mysqlでデータが文字化け・ブラウザに画像表示されない)