🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
MySQL

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

PHP

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

Q&A

解決済

2回答

2066閲覧

DBに保存されている画像を取得→表示する方法 掲示板アプリ

Katsuma-F

総合スコア6

MySQL

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

PHP

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

0グッド

0クリップ

投稿2019/10/14 09:04

編集2019/10/22 12:45

前提・実現したいこと

PHPで画像とテキストを一枚のカードにして投稿し、表示する掲示板を作成しています。
テキストの保存-->表示はできているのですが、問題はデータベースに保存されている画像を表示する正しい方法がわからなくて困っています。
画像とテキストを投稿・表示された時には、以下のようなエラーメッセージが発生しました。

発生している問題・エラーメッセージ

Undefined index: image in createset.php on line 4 Undefined index: image in mypage.php on (画像を表示する箇所の.. <img src="<?php print(htmlspecialchars($post['image'], ENT_QUOTES)); ?>" class="card-img-top">)

該当のソースコード

createset.php

PHP

1<?php 2if (!empty($_POST)) { 3 if ($_POST['image'] !== '' && $_POST['title'] !== '' && $_POST['description'] !== '') { 4 $image = date('YmdHis') . $_FILES['image']['name']; 5 $_POST['image'] = $image; 6 7 // パーツセットの情報をデータベースに保存 8 $card = $db->prepare('INSERT INTO posts SET card_image=?, title=?, description=?, user_id=?, created_at=NOW()'); 9 $card->execute(array( 10 $_POST['image'], 11 $_POST['title'], 12 $_POST['description'], 13 $user['id'] 14 )); 15 16 header('Location: mypage.php'); 17 exit(); 18 } 19} 20 21?>

posts.php

PHP

1<?php 2// ユーザーidと投稿ユーザーidを照合し、全パーツセットを$limit件ずつ取得 3$posts = $db->prepare("SELECT u.name, u.sns_name, u.picture, p.* FROM users u, posts p WHERE u.id=p.user_id ORDER BY p.created_at DESC LIMIT {$start}, {$limit}"); 4 5// postsテーブルからデータを$limit件取得 6$posts->execute(); 7$posts = $posts->fetchAll(PDO::FETCH_ASSOC); 8 9?> 10

mypage.php

PHP

1<?php 2ini_set('display_errors', 1); 3session_start(); 4require('dbconnect.php'); 5 6include('createset.php'); 7 8include('paging.php'); 9include('posts.php'); 10 11?> 12 13 14 <center> 15 <a href="#" class="btn btn-danger col-12 mb-4 mx-auto" data-toggle="modal" data-target="#myModal">パーツセットを作成する</a> 16 </center> 17 18 <!-- My-Card-Items --> 19 <div class="row"> 20 <?php foreach ($posts as $post): ?> 21 <?php if ($_SESSION['id'] == $post['user_id']): ?> 22 <div class="col-12 col-sm-6 col-md-4 col-lg-4"> 23 <div class="card"> 24 <a href="#"> 25 <div class="row no-gutters card-area"> 26 <img src="<?php print(htmlspecialchars($post['image'], ENT_QUOTES)); ?>" class="card-img-top"> 27 </div> 28 </a> 29 <div class="title-area"> 30 <a href="view.php?card_id=<?php print(htmlspecialchars($post['card_id'])); ?>" class="title"><?php print(htmlspecialchars($post['title'], ENT_QUOTES)); ?></a> 31 </div> 32 <div class="profile-area"> 33 <div class="profile-thum"> 34 <a href="#"> 35 <img src="user_picture/<?php print(htmlspecialchars($post['picture'], ENT_QUOTES)); ?>" class="rounded-circle" alt="画像"> 36 </a> 37 </div> 38 <div class="profile-username"> 39 <a href="#" class="profile-username"><?php print(htmlspecialchars($post['name'], ENT_QUOTES)); ?></a> 40 </div> 41 <div class="sns-username"> 42 <p class="sns-username"><?php print(htmlspecialchars($post['sns_name'], ENT_QUOTES)); ?></p> 43 </div> 44 </div> 45 <div class="description-area"><?php print(htmlspecialchars($post['description'], ENT_QUOTES)); ?></div> 46 </div> 47 </div> 48 <?php endif; ?> 49 <?php endforeach; ?> 50 51 </div> 52 <!-- ./row --> 53 54 </div> 55 <!-- ./container --> 56 57 <!-- セット作成のモーダル設定 --> 58 <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" style="display: none;" aria-hidden="true"> 59 <div class="modal-dialog" role="document"> 60 <div class="modal-content"> 61 <div class="modal-header"> 62 <h5 class="modal-title" id="exampleModalLabel">パーツセットを作成する</h5> 63 <button type="button" class="close" data-dismiss="modal" aria-label="閉じる"> 64 <span aria-hidden="true">×</span> 65 </button> 66 </div> 67 <form action="" method="post" multipart="enctype/multipart"> 68 <div class="modal-body"> 69 <input type="hidden"> 70 <p> 71 <label for="id_file">セットの写真;</label> 72 <input type="file" name="image" value="test" id="id_file" required> 73 </p> 74 <p> 75 <label for="id_title">Title:</label> 76 <input type="text" name="title" class="form-control" placeholder="セットのタイトル" autofocus="autofocus" maxlength="50" id="id_title" required> 77 </p> 78 <p> 79 <label for="id_description">説明文:</label> 80 <textarea class="form-control" name="description" placeholder="このセットについての説明(280文字以内)" autofocus="autofocus" maxlength="280" id="id_description" required></textarea> 81 </p> 82 </div> 83 <div class="modal-footer"> 84 <button type="button" class="btn btn-secondary" data-dismiss="modal">閉じる</button> 85 <button type="submit" class="btn btn-danger" name="create_folder">作成</button> 86 </div> 87 <!-- ./modal-footer --> 88 </form> 89 </div> 90 <!-- ./modal-content --> 91 </div> 92 <!-- ./modal-dialog --> 93 </div> 94 <!-- ./modal --> 95

試したこと

$_FILESを利用し、画像を'日付 . 画像ファイル名'で保存後、prepareで処理。 (in createset.php)

$posts = $db->prepare("SELECT u.name, u.sns_name, u.picture, p.* FROM users u, posts p WHERE u.id=p.user_id ORDER BY p.created_at DESC LIMIT {$start}, {$limit}");

で、取得。 (in posts.php)

<?php foreach ($posts as $post): ?>

で、投稿、表示しています。 (in mypage.php)

<img src="<?php ?>">この形に沿って、もしくはそれ以外の方法でもいいので画像を出力する正しい方法について、回答をお願いします。


やはり、アクセス権を775, 777に変えて試しみましたが画像のアップロードができません。
画像アップロードができない原因となっているコードを教えていただきたいです。

$_POST['image'] = $image を $_POST['card_image'] = $image に変えました。

createset.php

1if (!empty($_POST)) { 2 if ($_POST['image'] !== '' && $_POST['title'] !== '' && $_POST['description'] !== '') { 3 $image = date('YmdHis') . $_FILES['image']['name']; 4 move_uploaded_file($_FILES['image']['tmp_name'], __DIR__ . 'card_image/' . $image); 5 $_POST['card_image'] = $image; 6 7 // パーツセットの情報をデータベースに保存 8 $card = $db->prepare('INSERT INTO posts SET card_image=?, title=?, description=?, user_id=?, created_at=NOW()'); 9 $card->execute(array( 10 $_POST['card_image'], 11 $_POST['title'], 12 $_POST['description'], 13 $user['id'] 14 )); 15 16 header('Location: mypage.php'); 17 exit(); 18 } 19} 20 21?>

createset.phpの先頭でこのコードを打つと、

createset.php

1<?php 2$uploaddir = __DIR__ . '/card_image' . '/'; 3$uploadfile = $uploaddir . basename(date('YmdHis') . $_FILES['image']['name']); 4var_dump(move_uploaded_file($_FILES['image']['tmp_name'], $uploadfile));


Undefined index: image in /Applications/MAMP/htdocs/Vinyl_App/createset.php on line 3
Undefined index: image in /Applications/MAMP/htdocs/Vinyl_App/createset.php on line 4
と、出力されました。


最終的にこのコードになりました。

createset.php

1<?php 2if (!empty($_POST)) { 3 if ($_FILES['image'] !== '' && $_POST['title'] !== '' && $_POST['description'] !== '') { 4 $image = date('YmdHis') . $_FILES['image']['name']; 5 move_uploaded_file($_FILES['image']['tmp_name'], __DIR__ . '/card_image' . '/' . $image); 6 $card_image = $image; 7 8 // パーツセットの情報をデータベースに保存 9 $card = $db->prepare('INSERT INTO posts SET card_image=?, title=?, description=?, user_id=?, created_at=NOW()'); 10 $card->execute(array( 11 $card_image, 12 $_POST['title'], 13 $_POST['description'], 14 $user['id'] 15 )); 16 17 header('Location: mypage.php'); 18 exit(); 19 } 20} 21 22?> 23

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2019/10/14 10:12

ドキュメントルートのサーバー内での絶対パスと、その掲示板phpらを置くパスの情報などもあれば、仮の例示もしやすいのですが。
Katsuma-F

2019/10/14 12:29 編集

回答を頂き、ありがとうございます。 すみません、ファイルのパス情報ということで合っていますか? Vinyl_App/   ∟card_image/ ←ついさっきmove_uploaded_file用に作りました。   ∟createset.php   ∟posts.php   ∟mypage.php
guest

回答2

0

ベストアンサー

PHP: $_FILES - Manual
$_FILESに格納されているアップロードファイルデータは、
一時的なところにファイルが生成されている仮のもので、
受信したphpの処理が終わると消えてしまいます

消えないよう、
PHP: move_uploaded_file - Manual
を使って分かる場所にファイルを移動して管理する必要があります。

$_FILESにどういうデータが記録されているかは
PHP: POST メソッドによるアップロード - Manual
に例示されているので読むべきです。
具体的なやり方も、そのページの
「例2 ファイルのアップロードを検証する」のサンプルコードが参考になるはずです。

php

1move_uploaded_file($_FILES['image']['tmp_name'], __DIR__ . '/card_image/' . date('YmdHis') . $_FILES['image']['name']);

などとするなど。
それと、アップロード元のファイル名($_FILES['image']['name'])をそのまま信用しないで、
別途ファイル名をphp側で自動生成することをお勧めします。
(アップロードデータを細工して、サーバーで使えない文字コードを詰めることも可能なため。)

アップロード時の処理:
・一時的ファイルを、webブラウザからアクセス可能な場所にコピーする(move_uploaded_file)
・コピー後のパス情報を、データベースに記録しておく。

表示の処理:
・データベースに保存してあるファイルのパスを、img要素に組み込んで出力。

--

すみません、サンプルコードを間違ってました。
PHP: 自動的に定義される定数 - Manual
__DIR__の解説
__DIR__には、ディレクトリを示す最後の区切り記号がつかないそうなので、
そこを直せばうまくいくと思います。

--

質問文、末尾の、
createset.phpの先頭でこのコードを打つと、
~~
と出力されました、は、
ファイルアップロードを伴わない状態で$_FILESにアクセスしていないでしょうか。
POST送信(form要素でmethod="POST")しつつ、
input要素でname="image" type="file"にしていて送信できていれば、
$_FILES['image']がカラになることはないと思うのですが。
if (isset($_FILES['image']))などの判定は必要かと思います。

投稿2019/10/14 09:10

編集2019/10/22 11:55
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Katsuma-F

2019/10/19 15:15

createset.phpはこのようにしてみたんですが、./card_imageに保存できません。webブラウザからアクセス可能な場所にコピーするというのは、$_SESSION['join] = $_POST のようなことをするという事でしょうか?もう少し詳細な情報を教えて頂けると幸いです。 if (!empty($_POST)) { if ($_POST['image'] !== '' && $_POST['title'] !== '' && $_POST['description'] !== '') { $image = date('YmdHis') . $_FILES['image']['name']; move_uploaded_file($_FILES['image']['tmp_name'], __DIR__ . 'card_image/' . $image); $_POST['image'] = $image; // パーツセットの情報をデータベースに保存 $card = $db->prepare('INSERT INTO posts SET card_image=?, title=?, description=?, user_id=?, created_at=NOW()'); $card->execute(array( $_POST['image'], $_POST['title'], $_POST['description'], $user['id'] )); header('Location: mypage.php'); exit(); } }
退会済みユーザー

退会済みユーザー

2019/10/21 00:31

> webブラウザからアクセス可能な場所にコピーするというのは、$_SESSION['join] = $_POST のようなことをするという事でしょうか? まったくずれています。 webブラウザからアクセス可能な場所というのは、webブラウザから http://example.com/foo/bar/baz.jpg のようにアクセスできる場所、DocumentRoot の下の公開ディレクトリ上に置くことを意味します。 > ./card_imageに保存できません webサーバープロセスがそのディレクトリにアクセスできるよう、アクセス権を緩和してください。 おそらく705や755であれば775あるいは777も試さないといけないかもしれません。
Katsuma-F

2019/10/21 04:19

ご返信ありがとうございます。 webブラウザからアクセス可能な場所にコピーすることについて、ご指摘ありがとうございます。理解できました。 card_imageのアクセス権が元々は755であったため、705, 775, 777に変えてファイルのアップロードを試してみたんですが、どのパターンも質問の最初に書いたUndefined index: image in /Applications/MAMP/htdocs/Vinyl_App/createset.php on line 4のエラーコードが出力され、./card_imageに保存できません。 DBのcard_imageカラムを見ると日時の情報だけが入っていました。これはcreateset.phpのプログラムを直せばいいという事なのか、それとも他のファイルのコードが間違っているのでしょうか?
退会済みユーザー

退会済みユーザー

2019/10/21 04:27

__DIR__ の説明、再確認したところ、ディレクトリを示す「/」が最後につかないそうなので、PHPコード上で補う必要があります。
Katsuma-F

2019/10/21 07:26 編集

move_uploaded_file($_FILES['image']['tmp_name'], __DIR__ . '/card_image' . '/' . $image); このコードに変えてアクセス権を一通り変えてみたんですが、./card_imageに画像をアップロードできません。このコードは合っていますか? createset.phpの先頭で、 $uploadfile = __DIR__ . '/card_image' . '/'; print_r($uploadfile); ↓ /Applications/MAMP/htdocs/Vinyl_App/card_image/ と出力されました。
退会済みユーザー

退会済みユーザー

2019/10/21 07:32

コピー先は、ディレクトリ名のみではなく、ファイル名もつけたほうがよいかと。
Katsuma-F

2019/10/21 11:50

すみません、ファイル名とういうのはdate('YmdHis') . $_FILES['image']['name']のことで合っていますか? $image = date('YmdHis') . $_FILES['image']['name'];としています。
退会済みユーザー

退会済みユーザー

2019/10/21 11:58 編集

コピー先のディレクトリ名とファイル名を連結したものの内容をvar_dump()とかしてファイルとして存在可能かどうかをチェックするのがひとつ。 $_POST['image'] = $image;をやめるのもひとつ。$_FILES['image']と重複させて使うのは良くないし、外部から来る変数を上書きすると混乱の元。別途ローカル変数を充てがうこと。
Katsuma-F

2019/10/22 11:39

質問を編集しました。 前と変わらず、画像は./card_imageに保存されず、DBには日時だけ保存されています。 記事を投稿するmypage.phpにおかしい部分がある可能性はありますか?
退会済みユーザー

退会済みユーザー

2019/10/22 11:48

$_FILES['image'] と $_POST['image'] の混在は解消できましたでしょうか。 それと、$_POSTへのコード内の書き込みは避けて、ローカル変数を使ったほうが良いです。$_POST['card_image']ではなく$card_imageなどとするとか。
Katsuma-F

2019/10/22 12:41

mypage.phpのこのコードを間違えていました。 <form action="" method="post" multipart="enctype/multipart"> ↓ <form action="" method="post" enctype="multipart/form-data"> そして、$_FILES['image'] と $_POST['image'] の混在を解消し、$_POST['card_image']ではなく$card_imageに変更しました。 初歩的なミスをしていました、すみません。色々なアドバイスを頂きありがとうございました。 おかげさまで画像の取得、保存、表示ができるようになりました! 本当にありがとうございました!
退会済みユーザー

退会済みユーザー

2019/10/22 13:18

そこでしたか、まさかの。よかったです。
guest

0

  • イメージローダ的なapiを用意し、idを指定して画像を呼ぶか
  • data:images/jpeg;base64など文字列化して埋め込む

のどちらかが有効です、私なら前者を選びます

投稿2019/10/15 01:10

yambejp

総合スコア116694

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

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

Katsuma-F

2019/10/22 13:01

今回は画像をフォルダに保存、表示する方法にいたしました。 次はイメージローダーファイルを作り、idを指定して画像を呼ぶ方法にしようと思いました。 ご助言をいただき誠にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問