画像関連

【PHP・MySQL】データベースに画像を保存・表示する方法 第4回「画像を表示する」

Sara

 
ここまでの記事はこちら

今回はデータベースに保存した画像を取得・表示していきます。

解説

画像を取得する

list.php を開いて、8~11行目を追加します。

images テーブルからcreated_at(作成日時)の新しい順でデータを取得しています。

画像を表示する

取得した画像データ $images を for ルーブを使って表示していきます。

list.php の5・8・11行目のコードを変更します。

8行目

画像の表示は、画像を出力する image.php ファイルを作成して行います。

image.php という名前でファイルを作成して、以下のようにコードを書きます。

image.php では

<img src="image.php?id=<?= $images[$i]['image_id']; ?>"

で渡された image_id を受け取って、その image_id から画像データを取得します。

12行目で image/jpg, image/png などの Content-type を指定してから画像データを出力します。

11行目

画像の名前とサイズを表示しています。

画像サイズはバイトで保存されているので、キロバイトに変換して小数点第二位まで表示させています。(1KB = 1,000B)

Lightboxの画像

最後に Lightbox 部分も修正しましょう。

list.php の 3・8・10行目のコードを変更します。

動作確認

これで画像表示は完成です!

画像が表示されていること、Lightbox も正しく表示されることを確認してください。

次に行うこと

次回は画像をデータベースから削除できるようにしていきます。

PHP・MySQL
カレンダー開発講座

カレンダーを開発しながら

  • MySQLにデータを保存・編集・削除・検索する方法
  • タブレット・スマートフォンに対応させる方法
  • Datetimepicker の使い方
  • CSV ファイルを使った祝日の表示

など幅広く学ぶことができる講座です。

何か開発してみたい方、より実用的なコードを学びたい方にオススメです。

guest
31 Comments
古い順
新しい順 人気順
Inline Feedbacks
View all comments
Daiki Matsuda
Daiki Matsuda
1 year ago

コメント失礼致します。
こちらのサイトを参考にプログラムの勉強をしております。

画像を保存し、表示するプログラムにてpdfを保存して同じように表示することは可能でしょうか。

Daiki Matsuda
Daiki Matsuda
1 year ago
Reply to  Sara

ありがとうございます!!
無事にリストの方で確認ができました!!
クリックした際に、拡大表示が出来ないのですが、その場合は諦めた方がよろしいでしょうか。

Daiki Matsuda
Daiki Matsuda
1 year ago
Reply to  Sara

何度もコメント返信頂き、ありがとうございます!!
「404 File Not Found」のページが表示され、データが読み込めなかったのですが、
もしかしたらlightboxはPDFに対応してないのでしょうか。

Last edited 1 year ago by Daiki Matsuda
Daiki Matsuda
Daiki Matsuda
1 year ago
Reply to  Sara
<?php
require_once('functions.php');


$pdo = connectDB();


if ($_SERVER['REQUEST_METHOD'] != 'POST') {
    // 画像を取得
    $sql = 'SELECT * FROM images ORDER BY created_at DESC';
    $stmt = $pdo->prepare($sql);
    $stmt->execute();
    $images = $stmt->fetchAll();


} else {
    // 画像を保存
    if (!empty($_FILES['image']['name'])) {
        $name = $_FILES['image']['name'];
        $type = $_FILES['image']['type'];
        $content = file_get_contents($_FILES['image']['tmp_name']);
        $size = $_FILES['image']['size'];


        $sql = 'INSERT INTO images(image_name, image_type, image_content, image_size, created_at)
                VALUES (:image_name, :image_type, :image_content, :image_size, now())';
        $stmt = $pdo->prepare($sql);
        $stmt->bindValue(':image_name', $name, PDO::PARAM_STR);
        $stmt->bindValue(':image_type', $type, PDO::PARAM_STR);
        $stmt->bindValue(':image_content', $content, PDO::PARAM_STR);
        $stmt->bindValue(':image_size', $size, PDO::PARAM_INT);
        $stmt->execute();
    }
    header('Location:list_1.php');
    exit();
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>Image Test</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
</head>
<body>
<div class="container mt-5">
    <div class="row">
        <div class="col-md-8 border-right">
            <ul class="list-unstyled">
                <?php for($i = 0; $i < count($images); $i++): ?>
                    <li class="media mt-5">
                      <div style=”position:relative;”>  
                            <iframe src=”image.php?id=<?= $images[$i][‘image_id’]; ?>” width=”300″ height=”200″></iframe>
                        <a href=”#lightbox” data-toggle=”modal” data-slide-to=”<?= $i; ?>” style=”position:absolute; top:0; left:0; display:inline-block; width:300px; height:200px; z-index:10;”>  
                       </a> </div>
                        <div class="media-body">
                            <h5><?= $images[$i]['image_name']; ?> (<?= number_format($images[$i]['image_size']/1000, 2); ?> KB)</h5>
                            <a href="javascript:void(0);" onclick="var ok = confirm('削除しますか?'); if (ok) location.href='delete.php?id=<?= $images[$i]['image_id']; ?>'"><i class="far fa-trash-alt"></i> 削除</a>
                        </div>
                    </li>
                <?php endfor; ?>
            </ul>
        </div>
        <div class="col-md-4 pt-4 pl-4">
            <form method="post" enctype="multipart/form-data">
                <div class="form-group">
                    <label>画像を選択</label>
                    <input type="file" name="image" required>
                </div>
                <button type="submit" class="btn btn-primary">保存</button>
            </form>
        </div>
    </div>
</div>


<div class="modal carousel slide" id="lightbox" tabindex="-1" role="dialog" data-ride="carousel">
  <div class="modal-dialog modal-dialog-centered" role="document">
    <div class="modal-content">
      <div class="modal-body">
        <ol class="carousel-indicators">
            <?php for ($i = 0; $i < count($images); $i++): ?>
                <li data-target="#lightbox" data-slide-to="<?= $i; ?>" <?php if ($i == 0) echo 'class="active"'; ?>></li>
            <?php endfor; ?>
        </ol>
        <div class="carousel-inner">
            <?php for ($i = 0; $i < count($images); $i++): ?>
                <div class="carousel-item <?php if ($i == 0) echo 'active'; ?>">
                  <iframe src="image.php?id=<?= $images[$i]['image_id']; ?>" class="d-block w-100" width="500" height="300"></iframe>
                </div>
            <?php endfor; ?>
        </div>
        <a class="carousel-control-prev" href="#lightbox" role="button" data-slide="prev">
            <span class="carousel-control-prev-icon" aria-hidden="true"></span>
            <span class="sr-only">Previous</span>
        </a>
        <a class="carousel-control-next" href="#lightbox" role="button" data-slide="next">
            <span class="carousel-control-next-icon" aria-hidden="true"></span>
            <span class="sr-only">Next</span>
        </a>
      </div>
    </div>
  </div>
</div>


<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>

何度もご回答ありがとうございます。
上記のプログラムで添付画像のようになってしまいます。
Microsoft EdgeやGoogle Chromeで試しましたが、同じ結果となってしまいます。
自分で解決出来ずに申し訳ございません。

2021-12-10 (4).png
Daiki Matsuda
Daiki Matsuda
1 year ago
Reply to  Sara

本当にありがとうございます!!
無事に確認することができました!
とんでもなく初歩的なミスにより、
Sara先生には大変ご迷惑をおかけして大変申し訳ありませんでした。

Sara先生の講座を今から受講し、これからもっと勉強して精進したいと思います!
本当にありがとうございました😭

Daiki
Daiki
1 year ago
Reply to  Sara

久しぶりの質問で失礼いたします。

先日はご丁寧な質問対応ありがとうございました。
PDF拡大を行なって気づいたのですが、
画像にカーソルを合わせなくても、lightboxで指定された範囲をクリックすることで拡大表記が出来ることだったのですが、
カーソルを画像にだけ合わせた時に拡大クリックすることは可能ではないなでしょうか。

一般人
一般人
1 year ago

コメント失礼致します!
ライトボックスを勉強している者です!

ライトボックスで画像を拡大後に右上に×ボタンをつけて、拡大画像を閉じる機能をつけたいと考えているのですが、それは実装可能でしょうか。

Earyo
Earyo
1 year ago

複数の画像ファイルを選択してデータベースに保存することは可能でしょうか。

kazuya
kazuya
4 months ago

コメント失礼します!!
こちらのサイトを参考に勉強させて頂いています。

保存した画像を表示しようとしたところ、画像が表示されたりされなかったりします。
プログラム、DB設定等全てこちらのサイト通りにしております。
こちらの解決方法がありましたらご教授頂きたいです。

スクリーンショット 2022-10-05 22.16.57.png
すももも
すももも
3 months ago

データベース内に追加もできていますし、データ自体もおそらく届いているのに表示ができません。新しい画像も追加し再度試みましたがやはりだめです。現在データベース内には画像データが二つある状態です。
環境としてはxamp vscode だけです。エラーメッセージは出ていません。新しい

スクリーンショット (61).png
すもももも
すもももも
3 months ago
Reply to  Sara

わかりました。一応ファイルは同じ階層にあります!そのカードで試してみますね!返信ありがとうございます。

追記ですが色々試していて、ファイルの中身を出力したりしていたところ、本来画像で出力される所が文字化けして出力されてしまい、ファイルが壊れてしまったのではと予測しました。そこで調べたところ

何やらfile get contentsの関数で受け取るとファイルが壊れると言う記事を発見し、それによるとphpのバージョンによって破損してしまうことがあるようです。
改善のために現在7.3?〜8.1.11にアップデートをして無事更新、apachiも動きますが、次はxamppのmysqlのadminボタンからdatabaseを開いたところ、本来表示されるものが表示されず、要約するとopensll mysqliの拡張機能をインストールしてくれといったエラー文が出るようになってしまいました。調べてみたところphp.iniで;を外すなどとあり試してみましたが改善致しません。
もはやこのブログとは関係ない質問になってしまいましたがこちらの改善方法はご存知ないでしょうか?
また正常に動くxampp内でのphpアップデート方法や、saraさんのおすすめの開発環境教えて頂きたいです。

すももも
すももも
3 months ago
Reply to  Sara

すいません、指摘の通りに直しましたが改善されません。こちらの画像で試してみてほしいです。一応私のコード載せておきますね。

image.php
<?php
require_once ‘functions.php’;

$pdo = connectDB();

$sql = DELETE FROM age_artworks WHERE image_id = :image_id’;
$stmt = $pdo->prepare($sql);
$stmt->bindValue(‘:image_id’, (int)$_GET[‘id’], PDO::PARAM_INT);
$stmt->execute();

header(‘Location:list.php’);
exit();
?>

list.php
<?php
require_once ‘functions.php’;

$pdo = connectDB();

if ($_SERVER[‘REQUEST_METHOD’] != ‘POST’) {
    // 画像を取得
    $sql = SELECT * FROM age_artworks ORDER BY created_at DESC;
    $stmt = $pdo->prepare($sql);
    $stmt->execute();
    $images = $stmt->fetchAll();
    // foreach ($images as $value) {
    //     print_r($value);
    // }
    // exit();

} else {
    // 画像を保存
    if (!empty($_FILES[‘image’][‘name’])) {
        $name = $_FILES[‘image’][‘name’];
        $type = $_FILES[‘image’][‘type’];
        $content = file_get_contents($_FILES[‘image’][‘tmp_name’]);
        $size = $_FILES[‘image’][‘size’];

        $sql = INSERT INTO age_artworks(image_name, image_type, image_content, image_size, created_at)
                VALUES (:image_name, :image_type, :image_content, :image_size, now())’;
        $stmt = $pdo->prepare($sql);
        $stmt->bindValue(‘:image_name’, $name, PDO::PARAM_STR);
        $stmt->bindValue(‘:image_type’, $type, PDO::PARAM_STR);
        $stmt->bindValue(‘:image_content’, $content, PDO::PARAM_STR);
        $stmt->bindValue(‘:image_size’, $size, PDO::PARAM_INT);
        $stmt->execute();

    }
    header(‘Location:list.php’);
    exit();
}
?>
<!DOCTYPE html>
<html lang=“ja”>
<head>
    <meta charset=“utf-8”>
    <title>Image Test</title>
    <link rel=“stylesheet” href=“https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css” integrity=“sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T” crossorigin=“anonymous”>
    <link rel=“stylesheet” href=“https://use.fontawesome.com/releases/v5.7.2/css/all.css” integrity=“sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr” crossorigin=“anonymous”>
</head>
<body>
<div class=“container mt-5”>
    <div class=“row”>
        <div class=“col-md-8 border-right”>
            <ul class=“list-unstyled”>
                <?php for($i = 0; $i < count($images); $i++): ?>
                    <li class=“media mt-5”>
                        <!– <a href=”#lightbox” data-toggle=”modal” data-slide-to=”<?=$i;?>“> –>
                            <img src=“./image.php?id=<?= $images[$i][‘image_id’]; ?> width=“100” height=“auto” class=“mr-3”>
                        </a>
                        <div class=“media-body”>
                            <h5><?= $images[$i][‘image_name’]; ?> (<?= number_format($images[$i][‘image_size’]/1000, 2); ?> KB)</h5>
                            <a href=“javascript:void(0);”
                               onclick=var ok = confirm(‘削除しますか?’); if (ok) location.href=‘delete.php?id=<?= $images[$i][‘image_id’]; ?>‘”>
                            <i class=“far fa-trash-alt”></i> 削除</a>
                        </div>
                    </li>
                <?php endfor;?>
            </ul>
        </div>
        <div class=“col-md-4 pt-4 pl-4”>
            <form method=“post” enctype=“multipart/form-data”>
                <div class=“form-group”>
                    <label>画像を選択</label>
                    <input type=“file” name=“image” required>
                </div>
                <button type=“submit” class=“btn btn-primary”>保存</button>
            </form>
        </div>
    </div>
</div>

<div class=“modal carousel slide” id=“lightbox” tabindex=“-1” role=“dialog” data-ride=“carousel” style=“position:fixed;”>
  <div class=“modal-dialog modal-dialog-centered” role=“document”>
    <div class=“modal-content”>
      <div class=“modal-body”>
        <ol class=“carousel-indicators”>
            <?php for ($i = 0; $i < count($images); $i++): ?>
                <li data-target=“#lightbox” data-slide-to=<?=$i;?> <?php if ($i == 0) {echo ‘class=”active”‘;}?>></li>
            <?php endfor;?>
        </ol>

        <div class=“carousel-inner”>
            <?php for ($i = 0; $i < count($images); $i++): ?>
                <div class=“carousel-item <?php if ($i == 0) {echo ‘active’;}?>>
                    <img src=“image.php?id=<?= $images[$i][‘image_id’]; ?> class=“d-block w-100”>
                </div>
            <?php endfor;?>
        </div>

        <a class=“carousel-control-prev” href=“#lightbox” role=“button” data-slide=“prev”>
            <span class=“carousel-control-prev-icon” aria-hidden=“true”></span>
            <span class=“sr-only”>Previous</span>
        </a>
        <a class=“carousel-control-next” href=“#lightbox” role=“button” data-slide=“next”>
            <span class=“carousel-control-next-icon” aria-hidden=“true”></span>
            <span class=“sr-only”>Next</span>
        </a>
      </div>
    </div>
  </div>
</div>

<script src=“https://code.jquery.com/jquery-3.3.1.slim.min.js” integrity=“sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo” crossorigin=“anonymous”></script>
<script src=“https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js” integrity=“sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM” crossorigin=“anonymous”></script>
</body>
</html>

S__8192105.jpg
すももも
すももも
3 months ago
Reply to  Sara

ちょくせつみてみたところこのようになりました

スクリーンショット (64).jpg
すももも
すももも
3 months ago
Reply to  Sara

[“tmp_name”]=> string(24) “C:\xampp\tmp\phpC184.tmp” [“error”]=> int(0) DUMPしてみたらどうやらtempにエラーが出ているのでファイルが保存できてないようです。

すももも
すももも
3 months ago
Reply to  すももも

list.phpにて

var_dump($_FILES[‘image’]);
        print_r($http_response_header);
        exit();

array(6) { [“name”]=> string(14) “S__8192105.jpg” [“full_path”]=> string(14) “S__8192105.jpg” [“type”]=> string(10) “image/jpeg” [“tmp_name”]=> string(24) “C:\xampp\tmp\php9ABD.tmp” [“error”]=> int(0) [“size”]=> int(316884) } DUMPしてみたらこんな感じです。
すいませんあげなおしです
image.php
<?php
require_once ‘functions.php’;

$pdo = connectDB();
$id = $_GET[‘id’];
$sql = SELECT * FROM age_artworks WHERE image_id = :image_id LIMIT 1;
$stmt = $pdo->prepare($sql);
$stmt->bindValue(‘:image_id’, $id, PDO::PARAM_INT);
$stmt->execute();
$image = $stmt->fetchAll();

header(‘Content-type: ‘ . $image[‘image_type’]);
echo $image;
exit();
?>

すももも
すももも
3 months ago
Reply to  Sara

以前と変わらずこの状態です。fetchallはDBのカラムを全要素、配列にいれたくてそうしました。一応戻して直接開いてみましたら表示はされるのですがこのように本来の画像が表示されません。お手上げ状態です。前の質問に挙げた画像が悪いのでしょうか?。。。それかそもそも保存がうまくできてないのでしょうか。

スクリーンショット (65).png
ABOUT ME
Sara
Sara
運営者
書籍やオンライン講座でプログラミングを勉強してフリーランスのプログラマーになりました。
このサイトでは「わかりやすく・シンプル」をモットーに、プログラミングの基礎からアプリ開発まで紹介します。
独学でプログラミングを勉強をしている方、基礎は勉強したけれど次に何をすれば良いか分からない...という方のお役に立てるサイトを目指しています。
31
0
この記事にコメントするx
記事URLをコピーしました