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

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

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

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

Q&A

解決済

2回答

1806閲覧

PHPで送信した画像を選択したままにする方法

退会済みユーザー

退会済みユーザー

総合スコア0

PHP

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

0グッド

1クリップ

投稿2021/04/17 17:03

前提・実現したいこと

PHPで投稿フォームにて画像を送信し、別のところでバリデーションに引っ掛かった時、(例えば価格でバリデーションおきた)画像は選択したファイルを残したい。

わかりにくいと思うので、具体例を挙げます。
例:タイトル

①タイトル未入力の状態だと以下のようにバリデーション
イメージ説明

②タイトル入力状態だと、$_POSTされたタイトルがフォームに残る
イメージ説明

これが実現できるのは、

<input type="text" class="form-control" id="title" name="title" value="<?php if(isset($title)) echo h($title) ?>" placeholder="タイトルを入力してください(30文字以内)">

で、

value="<?php if(isset($title)) echo $title ?>"

があるから。

ここで本題です。
上記のタイトルの例のように画像も選択して送信したとします。

もし他のところでバリデーションに引っ掛かったとしても、画像ファイルは選択された状態にしたいです。
(タイトルのように、またわざわざ画像選択するのは億劫なので。)

ただ、タイトルとかはinput type="text"なので、

value="<?php if(isset($title)) echo h($title) ?>"

で表示できるのですが、画像の場合、file形式なので、

value="<?php if(isset($img)) echo $img ?>"

みたいにしても、タイトルのように表示できません。

<?php session_start(); require_once(ROOT_PATH .'/Models/Post.php'); require_once(ROOT_PATH .'function.php'); ini_set('display_errors', "On"); $obj = new Post(); $err = []; if($_SERVER['REQUEST_METHOD'] === 'POST'){ $title = filter_input(INPUT_POST, 'title'); $text = filter_input(INPUT_POST, 'text'); $category = filter_input(INPUT_POST, 'category'); $price = filter_input(INPUT_POST, 'price'); // 画像 $img = basename($_FILES['img']['name']); $img_err = $_FILES['img']['error']; $imgsize = $_FILES['img']['size']; $tmp_path = $_FILES['img']['tmp_name']; $upload_dir = 'img/'; $save_filename = date('Ymdhis').$img; $save_path = $upload_dir.$save_filename; // タイトル、詳細、カテゴリー、参考価格のバリデーション if(empty($title) || mb_strlen($title) > 30) { $err['title'] = "タイトルは必須です。また、30文字以内で入力してください。"; } if(empty($text) || mb_strlen($text) > 3000) { $err['text'] = "サービスの詳細は必須です。また、3000文字以内で入力してください。"; } if(empty($category)) { $err['category'] = "カテゴリーを以下のセレクトボックスから選択してください"; } if(empty($price) || !preg_match("/^[0-9]+$/", $price)) { $err['price'] = "サービスの参考価格を半角数字で入力してください。"; } // 画像ファイルのバリデーション // ①画像ファイルがあるか if(is_uploaded_file($tmp_path)) { // 画像データを移動 move_uploaded_file($tmp_path, $save_path); } else { $err['img'] = "画像を保存できませんでした。"; } // ②拡張子は画像形式か $allow_ext = array('jpg', 'jpeg', 'png'); $file_ext = pathinfo($img, PATHINFO_EXTENSION); if(!in_array(strtolower($file_ext), $allow_ext)) { $err['img'] = "画像ファイルを添付してください。"; } // ③ファイルのサイズが1MB未満か if($imgsize > 1048576 || $img_err == 2) { $err['img'] = "ファイルのサイズは1MB未満にしてください。"; } // エラーがなければ、DBにデータを保存し、リスト一覧にページ遷移 if(count($err) === 0) { $result = $obj->createList($_POST, $save_path); $_SESSION['list_msg'] = "リストの投稿に成功しました!"; header('Location: index.php'); exit; } } ?> ここからHTMLのフォーム <form action="" method="POST" enctype="multipart/form-data" id="p-form"> <!-- サービスの参考価格 --> <h6 id="p-price"><label for="kome"><font color="red">*</font></label>サービスを利用する際の参考価格</h6> <?php if(isset($err['price'])): ?> <p class="err_one"><font color="red"><?php echo $err['price'] ?></font></p> <?php endif; ?> <div class="mb-3"> <input type="text" class="form-control" id="p-price_form" name="price" placeholder="29800" value="<?php if(isset($price)) echo h($price) ?>"> </div> <!-- 画像 --> <h6 id="p-image">画像を追加してください</h6> <?php if(isset($err['img'])): ?> <p class="err_one"><font color="red"><?php echo $err['img'] ?></font></p> <?php endif; ?> <input type="hidden" name="MAX_FILE_SIZE" value="1048576"> <input type="file" class="form-control" id="p-image_upload" name="img" value="<?php if(isset($img)) echo h($img) ?>"> <!-- リスト投稿ボタン --> <div class="p-btn"> <button type="submit" class="btn btn-primary" id="p-btn_btn">リストを投稿する</button> </div> </form>

##試したこと

value="<?php if(isset($_FILES['img']['name'])) echo $_FILES['img']['name'] ?>">

と書いてみたが、効果なし

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

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

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

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

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

guest

回答2

0

前提としてtype=fileで選択した画像をそのまま選択した状態にすることはできません。
ブラウザからローカルのパスを参照することはできないという意味ですね。それができてしまうとブラウザからユーザのマシンに幾らでも悪さができてしまいます。

やるとしたらfileのバリデーションが問題なかったら一時ファイルとしてアップロード処理をしたうえでimgタグで参照させるくらいでしょうか。

投稿2021/04/17 23:33

m.ts10806

総合スコア80875

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

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

退会済みユーザー

退会済みユーザー

2021/04/18 13:24

そうだったんですね。 考え方ありがとうございます。
guest

0

ベストアンサー

上記のソースを実行したときに、どのように表示されて、期待しているものと違っているのでしたら、その差異も提示した方が良いと思います。

もし、ファイル名しか表示されていないのが、”効果なし”としているのでしたら、
$_FILES['img']['name']
に入っているのは、ユーザが入力したローカル環境のパス名を含んだファイル名では無いからでは?

なので、実現するのでしたら、ファイル名を別途、取得する方法を考えるか、パスを含んだファイル名は諦めて、保存された画像を表示するようにしてはどうでしょうか?
$save_pathにファイルを保存したパスが入っているようなので、img タグで表示してあげれば、ユーザにもアップされたことが解って良いと思います。パスを含んだファイル名にこだわる理由が無いのであれば、考慮する価値はあると思います。

投稿2021/04/17 22:33

nfox

総合スコア231

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

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

退会済みユーザー

退会済みユーザー

2021/04/18 13:26

承知いたしました。 ご教示いただきましてありがとうございます。 もう少しやり方考えてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問