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

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

ただいまの
回答率

89.97%

formで取得した画像を確認画面で表示する方法

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 8,688

SugiuraY

score 245

お世話になります。

①画像を投稿するページ
input.php
②上記の投稿ページからPOSTメソッドのアクションとして飛び内容を確認するページ
confirm.php
③Content-Type:image/jpegのヘッダーで画像を処理するページ
img.php

の3つのページがあります。
一旦、RDBを経由せずに確認画面であるconfirm.phpで画像を表示させたいのですが、方法のアドバイスをください。
これまで調べた結果、ヘッダーはそれぞれのページで一つであることから、外のimg.phpを作成して、これをimg src="img.php" という形が一般的であるということまでわかりました。

ただ、ここでわからない点は、POSTで画像のデータを$_FILESの中に格納して、confirm.phpには渡すことができるのですが、img.phpに同時にどのようにデータを渡すのかがわかりません。
POSTでもSessionでも同時に複数のファイルに値を渡すという感覚は持っていないのですが、実際にどのように処理させればよろしいのでしょうか?

よろしくお願い申し上げます。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 4

checkベストアンサー

+2

画像を何のためにconfimで一度表示したいかによりますね
単に選んだ画像がただしいかどうかをユーザーに確認させたいだけなら
送る前にチェックさせられます

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$(function(){
  $('input[type=file]').on('change',function(){
    var me=$(this);
    var file = $(this).prop('files')[0];
    var fr = new FileReader();
    if(file.type.match(/^image/)){
      me.next('.myimgs').remove();
      var imgtag=$('<img alt="test" class="myimgs" width="100">');
      me.after(imgtag);
      fr.onload = function() {
        imgtag.attr('src', fr.result);
      }
      fr.readAsDataURL(file);
    }
  });
});

</script>
<form action="confirm.php" method="post" enctype="multipart/form-data">
<input type="file" name="img1"><br>
<input type="file" name="img2"><br>
<input type="file" name="img3"><br>
<input type="submit" value="upload">
</form>

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/02/23 20:07

    違う角度からのご回答ありがとうございます。目的はおっしゃる通りのため、情報を頂きありがとうございます

    キャンセル

+2

input.phpでは、以下のような感じでファイルを送信しているという認識でよろしいでしょうか?

<form action="confirm.php" method="post" enctype="multipart/form-data">
<input type="file" name="img1" />
<input type="submit" value="ファイルを送信" />
</form>

アップロードされたファイルの実態はPHPによってテンポラリディレクトリに保存され、保存されたファイル名が$_FILES['img1']['tmp_name']に格納されます。このファイルはconfirm.phpがWebブラウザにレスポンスを返しきった時点で自動的に削除されてしまいますので、move_uploaded_fileを利用し適当なディレクトリに移動してあげる必要があります。

POSTメソッドによるアップロード

ファイルの移動先として2つ候補が考えられます。

  • 1. Apache等のhttpdでアクセスできるディレクトリに移動する
  • 2. それ以外のディレクトリに移動する

1の場合、img.phpなど経由せずパスを指定してあげれば直接アクセスできるようになります。
2の場合、img.phpでファイルを読み込み、画像ファイルのヘッダと一緒に返却してあげることによって画像の表示を実現します。

今回のご質問は2の方法で、かつimg.phpにどのようにファイル名を渡してあげるかとのことですが、セッションが使えるのでしたら、移動後のファイル名をセッションで受け渡してあげれば問題ないと思います。
GETパラメータで受け渡してあげる方法もありますが、ファイル名がURLに表出してしまうのはセキュリティ上あまりよろしくないので、セッションを利用した方が無難だと思われます。

以下のコードは一例です。

 confirm.php
<?php
session_start();
if (is_uploaded_file($_FILES['img1']['tmp_name'])){
    $tmp_filename = UPLOAD_TMP_DIR.basename($_FILES['img1']['tmp_name']);
    move_uploaded_file($_FILES['img1']['tmp_name'], $tmp_filename);
    $_SESSION['img1'] = $tmp_filename;
?>
    <img src="img.php" />
<?php
} else {
?>
エラー
 img.php
<?php
session_start();
header('Content-type: image/jpeg');
readfile($_SESSION['img1']);

最後にこのコードだけですと問題がありまして、move_uploaded_fileで一旦移動したファイルは自主的に消してあげない限り永遠に残り続けます。
confirm.phpというファイル名から察しまして、恐らく確認画面でキャンセル処理もできると推察されますが、一旦キャンセルしてファイルを上げ直した場合、最初にアップロードしたファイルは利用されないにも関わらず、残り続けます。
なので、バッチなどで定期的に使っていないファイルを削除してあげる必要があるかもしれません。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/02/23 08:46

    おはようございます。
    ご回答ありがとうございます。
    1.input.phpはまさにおっしゃるイメージです。
    2.$tmp_filename = UPLOAD_TMP_DIR.basename($_FILES['img1']['tmp_name']);
    move_uploaded_file($_FILES['img1']['tmp_name'], $tmp_filename

    このコードが不思議だったのですが、postされた場合、confirm.phpで$_FILESで、受け取れるため、これを$_SESSIONに渡すでは誤りでしょうか?投稿が確定した際に、データベースに格納し、それまではSESSIONでもっていれば良いかと安易に考えていましたが、いちど必ずテンポラリディレクトに保存する理由をご教示願えますでしょうか?
    3.2.の点を前提におなじimg.phpをSESSION変数で使い回すと思っていましたが、都度にテンポラリディレクトリからファイル自体を、削除する必要があるというご指摘でしょうか
    宜しくお願い致します。

    キャンセル

  • 2017/02/23 10:17

    【2について】
    本文にも書きました通り、confirm.phpの処理が終わった時点でPHPによりファイルが削除されてしまうためです。
    試しに、confirm.phpを以下のように直して確認してみてください。
    ・confirm.php
     $_SESSION['img1'] = $_FILES['img1']['tmp_name']; // /tmp/phpXXXXXX
     echo file_exists($_SESSION['img1'])?'true':'false'; // true
    ・img.php
     echo file_exists($_SESSION['img1'])?'true':'false'; // false

    【3について】
    上記の理由から、PHPの管理外のテンポラリファイルを削除しないとファイルがゴミとして残り続けるからです。

    キャンセル

  • 2017/02/23 20:06

    ご回答ありがとうございます。 非常に、わかりやすいご回答助かります。
    言葉足らずで申し訳ございませんが、confirm.phpの処理はRDBへのバイナリデータとMIME情報の格納を含んでいるため、その処理後にファイルが削除されて問題ございません。

    キャンセル

+1

画像ファイルが元々あるのなら、リダイレクト先のconfirm.phpへファイルパスまたはURL先の$img_pathと画像ファイル名$img\fileを送り、次のコードを吐き出させて表示させます。

echo "<img src='".$img_path."//".$img_file."//>";


また、画像ファイルが一時的にアップロードされたり、グラフのように画像生成されるのなら、

echo "<img src='http://ドメイン名/img.php?withd=".$width."&height=".$height."'//>";


などとURL引数を介して画像生成させて返させます。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/02/23 08:47

    ご回答頂きありがとうございます。

    キャンセル

+1

実際に試したわけではないですし、標準的な方法かどうかもわかりませんが、セッションに画像データ自体を入れてしまうのはいかがでしょうか。

confirm.php

session_start();
$_SESSION['upimg'] = file_get_contents($_FILES['upimg']['tmp_name']);
echo '<img src="img.php">';


img.php

session_start();
header('Content-type: image/jpeg');
echo $_SESSION['upimg']);


confirmからの飛び先.php

session_start();
file_put_contents(ファイル名, $_SESSION['upimg']);


セッション自体に画像データを入れてしまうことで、後始末などの面倒な処理が省けるのが利点かと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/02/23 20:08

    ご回答ありがとうございます。
    おっしゃる方法が当方も調べた限り、もっとも一般的なように思えます

    キャンセル

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

  • ただいまの回答率 89.97%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる