• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:WordPressの質問(q10177232)の続)

WordPressでのファイルアップロードの選択肢

このQ&Aのポイント
  • WordPressでFetch APIを利用してファイルをアップロードする方法が困難であることに悩んでいる。
  • Ajaxを使ったファイルアップロード方法は多く存在するが、データベース保存が見つからず、サーバーディレクトリ保存が推奨される。
  • 適切なアップロード方法を選定する際に、Fetch APIの利用可能性が判断基準となる。

質問者が選んだベストアンサー

  • ベストアンサー
  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.39

・ローカルストレージなどに保存しないと入力内容が消えるのではないかというアドバイス これは私は疑問に感じています。 消えるのかどうかわからないです。 どちらかと言うと消えないと思っています。 必ず消えるとかでないのなら、消えた場合に入力画面に戻るようにして、再入力してもらえばいいと思います。 消えないと言うか消えてもいいと言うか、セッションならこれは問題になりません。 私が想像しているセッションを使う場合の補足ですが、セッションは確定した登録用のものです。 表示切り替えはクライアント側のデータをそのまま使いまわします。 なのでサーバー側(セッション内容)とクライアント側のデータに相違があることがあるかもしれません。 それは確認画面まで進んでクライアント側のデータが改ざんされた場合ですが、それは無視します。 安全で確定したセッション内容を優先するからです。 そうすれば、確認画面から結果画面へ行く時は、「確認画面から結果画面へ行くよ」と言う情報しか(改ざんされたデータがない)サーバーに送信しないので安全です。

php_learn
質問者

補足

Q.ローカルストレージなどに保存しないと入力内容が消えるのではないかというアドバイス 必ず消えるとかでないのなら、消えた場合に入力画面に戻るようにして、再入力してもらえばいいと思います。 消えないと言うか消えてもいいと言うか、セッションならこれは問題になりません。 確認画面から結果画面へ行く時は、「確認画面から結果画面へ行くよ」と言う情報しか(改ざんされたデータがない)サーバーに送信しないので安全です。 A.回答ありがとうございます、dell_ok さんと同じように考えている方もおられるようで消えないかもしれません… 条件で消えるようであれば再入力してもらう方法がよさそうですね。 非同期通信という事で画面が還移する場合と違うのではないかと心配になっておりました。データをチェックして対策すれば問題ということでコードを考えていきます。

その他の回答 (38)

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.8

functions.phpもですが、これだけにはされてないですよね。 このファイルは基本的に追記してきたはずなのでわざわざ言いませんでしたが、他の部分を消されていたらいけないので確認です。

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.7

single-complete.phpのコードはこれだけですか。 私の書き方がよくなかったですね。 new-complete.phpの<script>以降をこのコードにしてください。 new-complete.phpは廃止したいので、それをsingle-complete.phpにコピーしてください。

php_learn
質問者

補足

回答ありがとうございます、functions.phpは追記しておりますので、以前のコードは残っております。 single-complete.phpを修正してみたのですが、new-complete.phpのnew-complete.phpの<script>以降というのは回答No.2のコードで良いのでしょうか?間違えておりましたらご指摘お願い致します。 回答画面を表示してみたのですが回答を確認するボタンが機能しておらずfunctions.phpが機能しているのか確認が取れておりません… new-complete.phpは廃止いたしました。 ※最新コード https://wandbox.org/permlink/PyoDzRL7TDD02EWm ※回答No.2 https://wandbox.org/permlink/Dp1Xqp400VTpr7wT ※表示一覧画面 https://www.irasuto.cfbx.jp/%e9%9b%91%e8%ab%87%e6%8e%b2%e7%a4%ba%e6%9d%bf%e3%80%80%e7%99%bb%e9%8c%b2%e7%b5%90%e6%9e%9c%e7%94%bb%e9%9d%a2/

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.6

コードを確認したいので、最新のfunctions.phpとsingle-complete.phpだけをアップしてください。他のファイルは不要です。 私の方で動いて質問者さまの方で動かないのは、基本的に環境の違いやデータの違いによるものです。 でなければコードに誤りがあることになりますので、私が書いた通りかどうか確認します。 new-complete.phpは廃止しましょう。 質問一覧からはsingle-complete.phpが呼ばれるように私の環境を戻しておきます。 ただ、コードは先日までのnew-complete.phpがベースなので気を付けてください。

php_learn
質問者

補足

回答ありがとうございます。new-complete.php単体で試してみたのですが同じものが表示されているため、single-complete.phpが原因ではなくfunctions.phpの読み込みに失敗していると思われます。 アドバイスお願い致します。 ※現在のコード https://wandbox.org/permlink/Oc9fcaTwdlEss88I

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.5

・single-complete.phpのコードを変更してみたのですが new-complete.phpでやっていないのですか。 それともnew-complete.phpの内容をまるまるコピーしたうえで変更されましたか。 私は固定ページのテンプレートをこちらを呼ぶようにしてnew-complete.phpでやっています。

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.4

なぜ https から書かれたのかわかりませんが、自サイトのURLの関数 home_url があるので不要です。 私が書いたとおりのものにしてください。 ---- fetch('<?php echo home_url('https://www.irasuto.cfbx.jp/wp-content/wp-admin/admin-ajax.php'); ?>', opt) // 送信先 Wordpressの場合変更不可能 ---- でなければ、直接URLを書いてください。 まあ、サイトURLが変わったら直すのが大変なのでおすすめしません。 書くにしても /wp-content は不要なので気を付けてください。 ---- fetch('https://www.irasuto.cfbx.jp/wp-admin/admin-ajax.php', opt) // 送信先 Wordpressの場合変更不可能 ----

php_learn
質問者

補足

回答ありがとうございます、修正いたしました。

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.3

・// ここから表示する内容に確認画面のコードを書く必要があり、どのように書けばよいのか分からない状態です。 このコードは functions.php に書いてください。 コードの元になっている参考サイト(https://imuza.com/enquiry-form/)にはその説明がまったくありませんが、常識なのかもしれませんね。 処理内容は以下のようにしてください。 とりあえず送信されてきた入力内容をそのままJSON形式にして出力しています。 今はチェックやデータ保存のことは考えず、まずはAjax送受信の動作を成功させるのが目的です。 ----functions.php function enquiry_sample() { header('Content-type: application/json; charset=UTF-8'); $result = []; $result['namae'] = $_POST['namae']; $result['message'] = $_POST['message']; $result['stamp'] = $_POST['stamp']; echo json_encode($result); exit; } add_action('wp_ajax_enquiry_sample', 'enquiry_sample'); add_action('wp_ajax_nopriv_enquiry_sample', 'enquiry_sample'); ---- 回答画面のコードも修正してください。 ---- <div id="result"> <p id="result_namae"></p> <p id="result_message"></p> <input type="radio" id="result_stamp"><label for="result_stamp"></label> </div> <script> document.getElementById("submit_button").addEventListener('click', (e) => { const formData = new FormData(community_form); // フォームデータをオブジェクトに収容する formData.append('action', 'enquiry_sample'); // サーバーのアクション名 const opt = { method: 'post', body: formData //fetch() を使って FormData をサブミットするには、 送信オプションの body に FormData オブジェクトをセット } fetch('<?php echo home_url('/wp-admin/admin-ajax.php'); ?>', opt) // 送信先 Wordpressの場合変更不可能 .then(response => { //成功したら(then) ,responseのデータをコンソールに表示 if (!response.ok) { throw new Error; } return response.json(); }) .then(json => { document.getElementById('result_namae').innerHTML = json.namae; document.getElementById('result_message').innerHTML = json.message; document.getElementById('result_stamp').value = json.stamp; document.forms['community_form'].style.display = 'none'; //document.getElementById('result').style.display = 'block'; }) .catch(error => {}); }); </script> ---- 私の方ではこれで動作確認できました。

php_learn
質問者

お礼

Content-Type : application/json が原因かと思い変更してみたのですが、同じものが表示されているためfunctions.phpに原因があるようです。 ※表示画面 https://www.irasuto.cfbx.jp/%e3%83%86%e3%82%b9%e3%83%88-2/ ※表示に成功したコード http://web.mt-systems.jp/archives/1179 ※参考サイト http://web.mt-systems.jp/archives/1179 https://celtislab.net/archives/20180727/ajax-fetch/ ※変更後のコード <div id="result"> <p id="result_namae"></p> <p id="result_message"></p> <input type="radio" id="result_stamp"><label for="result_stamp"></label> </div> <script> document.getElementById("submit_button").addEventListener('click', (e) => { const formData = new URLSearchParams(community_form); // フォームデータをオブジェクトに収容する formData.append('action', 'enquiry_sample'); // サーバーのアクション名 const opt = { method: 'post', body: formData //fetch() を使って FormData をサブミットするには、 送信オプションの body に FormData オブジェクトをセット } fetch('<?php echo home_url('https://www.irasuto.cfbx.jp/wp-content/wp-admin/admin-ajax.php'); ?>', opt) // 送信先 Wordpressの場合変更不可能 .then(response => { //成功したら(then) ,responseのデータをコンソールに表示 if (!response.ok) { throw new Error; } return response.json(); }) .then(json => { document.getElementById('result_namae').innerHTML = json.namae; document.getElementById('result_message').innerHTML = json.message; document.getElementById('result_stamp').value = json.stamp; document.forms['community_form'].style.display = 'none'; //document.getElementById('result').style.display = 'block'; }) .catch(error => {}); }); </script>

php_learn
質問者

補足

回答ありがとうございます、single-complete.phpのコードを変更してみたのですが、スタンプの選択ボックスが1つしか表示されず失敗しております… Consoleを見てみたのですが直接的な原因ではなさそうです。回答画面ではなく単独で別途新規ページを作ってみたのですが、同じように表示されているため何か問題があるようです。 functions.phpに書くように教えて頂いたコードを同じファイルに置いてみたのですが改善されませんでした。 ※質問一覧表示画面 https://www.irasuto.cfbx.jp/%e9%9b%91%e8%ab%87%e6%8e%b2%e7%a4%ba%e6%9d%bf%e3%80%80%e7%99%bb%e9%8c%b2%e7%b5%90%e6%9e%9c%e7%94%bb%e9%9d%a2/

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.2

やり方はいろいろあるのでしょうから、どれを使うかは質問者さまが検討してください。 ただ、いきなり今のコードに含めるのではなく、テスト用の固定ページを作りなおかつそれが実行できる環境にしておいてから、参考サイトのコードを把握して導入してみてください。 動かないコードをいきなり出されても私の方では対応しきれませんので、必ずご自身の環境で動かしてみてくださいね。 エラーが出てわからない、と言う場合はコードをいただいて私の環境で試して確認しますので、それはそれで言ってください。 まずは、どのような仕組みでどのようなコードで実現できるかを把握するのが重要です。 さっとしか見ていませんが、参考サイトは、文字だけとか、ファイルアップロードだけ、とかのような感じなので、どちらも複合するのは本当に理解しないと難しいかも知れません。 ただ、それぞれのコードを混ぜただけでは、たぶん無理です。

php_learn
質問者

補足

A.回答ありがとうございます、色々と考えたのですが、Fetch APIは難しそうなので諦めてWordpressでAjaxを使う方法を調べて使うように考えております。dell_okさんに考えて頂いて申し訳ないです… 記事も少なくエラーに対応しきれない可能性があり、Wordpressだと通常とは異なるためそちらにも順応する必要があり今の自分の力だと手に負えない気がしています… dell_okさんからアドバイス頂いたコードを元に考えてみたのですが、// ここから表示する内容に確認画面のコードを書く必要があり、どのように書けばよいのか分からない状態です。 ※new-complete.phpが最新コードになります。 https://wandbox.org/permlink/Dp1Xqp400VTpr7wT

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.1

私の方でいろいろと試していたのですが思った以上に簡単でした。 ただ、その方法がいいかどうかはわかりません。 普通にフォームを送信するだけでできそうです。 名前やコメントもスタンプもファイルアップロードもこれだけでできそうです。 スタンプについては先日の処理は不要でした。 ---- document.getElementById("submit_button").addEventListener('click', (e) => { e.preventDefault(); // イベント動作を止める const formData = new FormData(community_form); // フォームデータをオブジェクトに収容する const opt = { method: 'post', body: formData //fetch() を使って FormData をサブミットするには、 送信オプションの body に FormData オブジェクトをセット } fetch('<?php echo home_url('質問回答受信'); ?>', opt) // 送信先 .then(response => { //成功したら(then) ,responseのデータをコンソールに表示 if (!response.ok) { throw new Error; } return response.json(); }) .then(json => { document.getElementById('result_namae').innerHTML = json.namae; document.getElementById('result_message').innerHTML = json.message; document.getElementById('result_stamp').value = json.stamp; document.forms['community_form'].style.display = 'none'; document.getElementById('result').style.display = 'block'; }) .catch(error => { }); }); ---- 送信に成功した後で表示する領域を</form>の下に追加しておいてください。 送信に成功した後で受信するデータはjsonを使っています。 上のコードで return response.json(); して json.namae を使っているのがそうです。 ---- <div id="result" style="display: none;"> <div>回答結果</div> <div><p>コメント:<span id="result_message"></span></p></div> <div><p>スタンプ:<input type="radio" id="result_stamp" disabled><label for="result_stamp"></label></p></div> <div><p>名前:<span id="result_namae"></span></p></div> </div> ---- WordPressがもっている非同期の機能も使わないでもっとわかりやすい方法で実装しています。 送信先は固定ページ「質問回答受信」です。 ファイル名は「community-receive.php」にしています。 とりあえず送信されてきたものをそのままjsonに変換して返しています。 ---- <?php /* Template Name: community-receive 固定ページ: 質問掲示板 質問回答受信 */ $post_json = json_encode($_POST); echo $post_json; ---- 実際は、ここでチェックしたり、データベースに保存したり、画像ファイルに保存したりします。 チェックや保存の処理は single-regist.php とほとんど同じで、主には$_SESSIONを$_POSTに変更するようになると思います。

php_learn
質問者

補足

A.回答ありがとうございます、Wordpressで非同期通信を行う場合に必須の条件というのがあるようでそちらの追加が必要なようです。 以前Wordpressは外部からのウイルスに対して防御するため外部からのAjax(非同期通信)を受け付けないようになっているとお伝えしていたことがあったと思うのですが、実際にはルールがありそれを守った場合に使えるようでした(wordpressサポートフォーラムで確認)。 その際にAsarKingChangさんからもアドバイスを頂いておりました内容を引用させていただきます。 ※wordpressとJavascriptでデータのやり取りを行う場合の条件 フロントを通してはダメです。STDINという標準入力をWordPressが破壊してしまう為、動作しません。 直接通信をかけてみてください。WordPressの初期化経路を通さずに、DBを使えば実現は可能と思います。 AJAXなので、接続はJavaScript側からなので。通信そのものには、WordPressは使えないです。 WordPressを通せばそれ自体がフロント動作をしてしまうので。(全部ぶった切れば、APIとしての出力=VIEWは確か行けるはずですが、STDINを乗っ取るのがきついはず) ________________________________ fetchを使いたい場合Wordpressを使う場合は下記参考サイトのような対応が必要なようです。 「ajaxを使わずに」という条件でもスクリプトで書き換える、ページ内で部分的に表示/非表示で切り替えるなど方法があるようですが、送受信は行わないので、サーバ側にデータは送れないとのことでした。 Wordpressで非同期通信を行う場合に必須の条件を書き出してみます。 1,WPでAjaxを利用するには「wp-admin/admin-ajax.php」を経由する・・・⑥を参考 2,Ajaxリクエスト時に nonce を送信する必要がある・・・①を参考 3,fetch()実行の際オブジェクトパラメータの「body」にPOSTデータを渡すとき、「JSON.stringify()」では解決しないため「URLSearchParams」オブジェクトを指定する・・・①②を参考 +α 1,データベースに直接保存する場合blob型を使うとうまくいった・・・③ ※①より抜粋 URLSearchParamsオブジェクトを指定 let params = new URLSearchParams(); params.append('action', 'ajax_func'); fetch('https://…/wp-admin/admin-ajax.php', {method: 'post', body: params}).then(function (response) { if (response.ok) { response.text().then(function (text) { alert(text); }); } }); add_action('wp_ajax_ajax_func', 'proc_ajax'); function proc_ajax () { die('hello'); } ※fetchを使ってWordPressとAJAX通信 ①http://web.mt-systems.jp/archives/1179https://celtislab.net/archives/20180727/ajax-fetch/ ※Ajaxのファイルアップロードについて ③https://accelboon.com/tn/wordpressajax%E3%81%A7%E7%94%BB%E5%83%8F%E3%82%92%E9%80%81%E5%8F%97%E4%BF%A1/ ※WordPress:Fetch(Ajax)でお問い合わせフォーム ④https://imuza.com/enquiry-form/ ※WordPressでファイルアップロードをAjaxでやる方法 ⑤https://blog.spicadots.com/2020/05/wordpress-file-upload-with-ajax/ ※WordPress|Ajaxでデータを取得する方法(脱jQuery) ⑥https://zenn.dev/unknow/articles/bf143d8443d70e

関連するQ&A