- ベストアンサー
WordPress URL設計の悩み
- WordPressでのURL設計について、1連番号とUUIDのどちらが適切か悩んでいる。
- 連番IDの安全性に関する意見や他の識別子の使用方法についての議論が存在する。
- 具体的な実装例や参考文献を通じて、選択肢の考察を求めている。
- みんなの回答 (29)
- 専門家の回答
質問者が選んだベストアンサー
・既存のコードから追加コードを探すのが大変になるため、追加行と追加コードを書いていきます。 私の方ではgitでソース管理しているので前回のものと比較は簡単にできるので書かなくても大丈夫ですよ。 「※最新コード」のURLが違うのか、ラジオボタンが type="feelingListbox" のままのようです。 ファイルのアップロードも名前やコメントやスタンプと同じところで処理すればいいので、FormDataに追加するのはそちらでやってください。 気になるのは fetch のURL /wp-admin/admin-ajax.php ですかね。 これでうまくいくのかどうか私の方では検証ができていません。
その他の回答 (28)
- dell_OK
- ベストアンサー率13% (766/5720)
それでしたら、こんな感じで。 ---- echo '<p>スタンプ:<input type="radio" value="'.$row->stamp.'" id="stamp" disabled><label for="stamp"></label></p>'; ----
補足
回答ありがとうございます、レンタルサーバーの不具合で試すことが出来ていないのですが… アップロードファイルも表示させることは可能でしょうか?
- dell_OK
- ベストアンサー率13% (766/5720)
・質問表示画面のデザインを考えて single-regist.php と同じように画像、メッセージ、スタンプ、名前を表示させたいのですが、 single-que_list.php の$rowsでSQLを実行することで画像とスタンプは表示可能でしょうか? single-regist.phpと同一のコードをsingle-que_list.phpに書く必要があるのではないかと考えております。 質問表示画面(single-complete.php)のことですか。 質問一覧画面(single-que_list.php)のことですか。
補足
回答ありがとうございます、申し訳ありません勘違いしていたようです。 質問表示画面(single-complete.php)に登録結果画面 (single-regist.php) と同じものを表示させたいと考えております。
- dell_OK
- ベストアンサー率13% (766/5720)
・document.addEventListener("DOMContentLoaded", init);に変更という形で良いでしょうか? はい。大丈夫です。
お礼
申し訳ありません、現在の状況についてお伝えしておくべきでした。 各ファイルのウイルス対策はすべて終えた状態で、質問表示画面から回答ページを作成していきたいと考えております。
補足
質問表示画面のデザインを考えて single-regist.php と同じように画像、メッセージ、スタンプ、名前を表示させたいのですが、 single-que_list.php の$rowsでSQLを実行することで画像とスタンプは表示可能でしょうか? single-regist.phpと同一のコードをsingle-que_list.phpに書く必要があるのではないかと考えております。 登録結果画面と一部同じものが表示されることになるのですが、その下に回答機能を付け加えて、その下に回答を表示させたいと考えております。 もう1点お聞きしたいのですが、回答機能を使いコメントしたものを送信後に真下に表示させるというのはAjaxが必要なのでしょうか? 別途PHPファイルを作る形になるのでしょうか? $query = $wpdb->prepare($sql); $rows = $wpdb->get_results($query); ※回答機能参考イメージ https://imgur.com/0iv1TEK.jpg ※現在のコード https://wandbox.org/permlink/BycIJ54XJxYFHuyh ※現在の質問一覧表示画面 http://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)
・代用する場合のちの文を変更する必要はありますでしょうか? document.addEventListener('input', e => {} を document.addEventListener("DOMContentLoaded", (e) => {} には変更できません。
補足
回答ありがとうございます、勘違いしておりました申し訳ありません。 window.addEventListener("load", init); を document.addEventListener("DOMContentLoaded", init);に変更という形で良いでしょうか?
- dell_OK
- ベストアンサー率13% (766/5720)
ところで、JavaScriptでXSS対策するのはやめたのでしょうか。
補足
回答ありがとうございます、XSSについてはすべてチェック済みでXSS対策済みとなっております。 dell_okさんに修正いただいたコードになるのですが、期待通りの動作をしているのなら問題ないようです。 気になるところとしては、インデントがところどころおかしいため読みにくい、window の load イベントで処理すると実行タイミングがとても遅れることがあるので、document の DOMContentLoaded イベントのほうが安全、maxlength 属性を使えばかなりコードは減らせそうとのことでした。 document.addEventListener('input', e => {} から document.addEventListener("DOMContentLoaded", (e) => {} 上記のアドバイスからに変更するほうが良いのではないかと考えているのですが、代用する場合のちの文を変更する必要はありますでしょうか?
- dell_OK
- ベストアンサー率13% (766/5720)
入力中の文字数チェックと、ボタン制御のための文字数チェックが別々になるのがよくない気もしますが、こんな感じでどうでしょうか。 ---- <script> function validation_submit(f) { const submit = document.getElementById("submit_button"); /* 判定は逆なので、逆に渡す */ submit.disabled = f ? false : true; }; function validation_text(parts) { /* このpartsグループの、inputを抽出 */ let text = parts.getElementsByClassName('input')[0]; /* 最小チェック */ if (text.value.length == 0) { return false; } /* 最大チェック */ if (text.value.length >= text.dataset.length) { return false; } return true; }; /* バリデーション条件判断部分 */ function validation() { let parts = document.getElementsByClassName('parts'); let submit = true; for (let i = 0; i < parts.length; i++) { if (validation_text(parts[i]) != true) { submit = false; } } validation_submit(submit); }; /* 例えばのチェック */ function init() { /* カメラ画像をファイルアップロード時に非表示にする */ /* 省略 */ /* 文字数表示 */ document.addEventListener('input', e => { if (!['name', 'message'].includes(e.target.id)) return; const t = e.target, m = t.nextElementSibling, n = t.value.length - (t.dataset.length | 0), c = document.createElement('span'); c.append(Math.abs(n)); m.style.color = n > 0 ? 'red' : 'black'; m.replaceChildren(n > 0 ? '' : '残り', c, `文字${n > 0 ? '超過してい' : '入力でき'}ます。`); /* 毎回判定によるボタン制御 */ validation(); }); /* 初回判定のボタン制御 */ validation(); }; window.addEventListener("load", init); </script> <body> <form method="post" enctype="multipart/form-data"> <div class=parts> <h2>名前(name)<span>※必須</span></h2> <input class=input type="text" name="name1" id="name" data-length="32" placeholder="未入力の場合は、匿名で表示されます" value=""> <div></div> </div> <div class=parts> <h2>コメント(comment)<span class="required">※必須</span></h2> <input class=input type="text" name="name2" id="message" data-length="40" placeholder="荒らし行為や誹謗中傷や著作権の侵害はご遠慮ください"> <div></div> </div> <div class="post-button"><!-- ボタンを押せなくする --> <button type="submit" id="submit_button" name="mode" value="confirm">表示画面へ進む</button> </div> </form> </body> ----
- dell_OK
- ベストアンサー率13% (766/5720)
・シンプルに document.addEventListener を使う方が簡単なのではないかと指摘を頂いております。 なんだかとてもすっきりしましたね。 ひとつ気になるのは、初期表示がないことくらいですかね。 ・名前とコメントの文字数をカウントする機能は window.onload を使わずにカメラ画像を画面表示後に呼ぶことは可能だと思われますでしょうか? document全体に対するinputイベントですし、対象の入力項目はイベントが発生してからの判定なのでDOMツリー構築完了前(入力コントロールが準備されていない)でも問題はないのでこのままでもいい気はします。 それはそうとして、初期準備はひとまとめにすると言うことで、まずはこの処理をinit(){}の中に入れます。 ---- function init() { /* カメラ画像をファイルアップロード時に非表示にする */ 省略 /* 文字数表示 */ document.addEventListener('input', e => { if (!['name', 'message'].includes(e.target.id)) return; const t = e.target, m = t.nextElementSibling, n = t.value.length - (t.dataset.length | 0), c = document.createElement('span'); c.append(Math.abs(n)); m.style.color = n > 0 ? 'red' : 'black'; m.replaceChildren(n > 0 ? '' : '残り', c, `文字${n > 0 ? '超過してい' : '入力でき'}ます。`); }); }; ---- それでと、window.onloadを使わずに、無難なaddEventListenerを使いましょうかね。 window.addEventListener("DOMContentLoaded", init); 「カメラ画像を画面表示後」と言うのであれば、イベントをloadにします。 window.addEventListener("load", init);
補足
A.アドバイスありがとうございます、名前、メッセージのIF分岐するコードはDOMツリー構築完了前で、 カメラ画像をファイルアップロード時に非表示にするコードは、イベント設定以前に要素を取得しているため、HTML解釈後に実行することが必要だと理解できました。 window.onloadを使わずにwindow.addEventListener("load", init);は不可能ではないかと思ったのですが、参考サイトのクロスブラウザの実装方法を見ると可能なようですね。 ※参考サイト https://so-zou.jp/web-app/tech/programming/javascript/event/handler/onload.htm#no6 function Init() { // 読み込み完了後の処理 } window.addEventListener("load", init); もう1点アドバイス頂いた問題を解決する必要があるのですが、条件にあわせて送信ボタンの使用権限を操作する機能を JS内変数でどのように格納すれば良いでしょうか? sample.php60行目の/* class=parts内の class=uso_inputに対して設定 */するコードを書いてから、/* バリデーション条件判断部分 */に反映する必要があるため、 どう対応するべきかわからずアドバイスお願い致します。 初めにdell_okさんにアドバイス頂いたコードでは、内部的に初期のDOM構築の時の値と 後から書き換えた物で、2つの値が発生していて、テキスト解析させる方がストレスになるので、 あまりいい事はないとの指摘を頂きました。 function lengthCheck() { const left = this.dataset.maxlength - this.value.length; if (left >= 0) { this.nextElementSibling.innerHTML = 'あと<strong>' + left + '</strong>文字'; this.dataset.submit_disabled = this.value.length === 0; } else { this.nextElementSibling.innerHTML = '<strong>' + -left + '</strong>文字超過しています'; this.dataset.submit_disabled = true; } let disabled = false; for (let i = 0; i < length_input.length; i++) { if (length_input[i].dataset.submit_disabled === "true") { disabled = true; } } submit_button.disabled = disabled; } _________________________ ※JS内変数でどのように格納するように変更されたコード(sample.phpに教えて頂いたコード、single-input.phpに考えたコードを書きました) https://wandbox.org/permlink/LR1ZL57D9PdHpcHD
- dell_OK
- ベストアンサー率13% (766/5720)
参考サイト「window.onloadの利用はお勧めしない その理由」(https://took.jp/window-onload/)の内容について私から補足しておきます。 引用:「一つしか動作できない」というのは、正確には、関数を上書きしてしまっている(オーバーライド)しているようです。 これを読んでああそうなんだと思うだけではいけません。 自分で実行してみて確認して初めて、このサイトの情報は正しいのだ、と言えますし、るのです。 実際にやってみてください。 以下のコードで確認できます。 参考サイトには「例えば、外部ライブラリの中にwindow.onloadの記述があった場合には、その機能が正常に動作しないなどのことも考えられます。」とありますが、自分自身にwindow.onloadの記述が複数あっても同じことです。 ---- <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> </head> <body> <script> function init() { alert("初期化"); } function setting() { alert("設定"); } window.onload = init;/*下のsettingで上書きされるため実行されない*/ window.onload = setting;/*上のinitを上書きする*/ </script> </body> </html> ---- 実行すると、"初期化"は表示されず、"設定"が表示されるだけになります。 どう言うことかと言うと、window.onloadは「windowがロードされたときのイベント」ですが、それに=で代入するということは、それそのものをこれとする、ということです。 window.onloadの全体が右辺のものになるということです。 例えば、こう書いたら、 ---- a = 1; a = 2; ---- aの値は2で上書きされてしまいます。 これと同じことで、1を代入したことはなかったことになるわけです。 次に、addEventListener("DOMContentLoaded",でやってみましょう。 ---- <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> </head> <body> <script> function init() { alert("初期化"); } function setting() { alert("設定"); } window.addEventListener("DOMContentLoaded", init); window.addEventListener("DOMContentLoaded", setting); </script> </body> </html> ---- "初期化"が表示され、"設定"も表示されるはずです。 addEventListenerは「add」の名前の通り「追加」を意味します。 上書きではなく、追加です。 DOMContentLoadedの時のイベントに、initを追加し、settingを追加します。 追加なので、それぞれを実行することになります。 参考サイトが伝えたいことはこのようなことだと思います。 では、addEventListenerを使えばいいのだ、ではありません。 下手に使うとよくないことが起こります。 ループの中でaddEventListenerで無名関数を追加した場合です。 ---- <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> </head> <body> <script> for (let i = 0; i < 2; i++) { window.addEventListener("DOMContentLoaded", function () { alert("初期化"); }); } </script> </body> </html> ---- "初期化"が2回表示されます。 無名関数内でその繰り返しに関係のある変数などを使っていない場合は、まったく同じ処理がループの回数分追加されまったく意味がないどころか、余計な負荷を発生させかねません。 以下のように関係のある関数を使う場合は別の処理として意味のあるものになります。 ---- <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> </head> <body> <script> for (let i = 0; i < 2; i++) { window.addEventListener("DOMContentLoaded", function () { alert(i); }); } </script> </body> </html> ---- 他にも使う際の注意点はあると思いますがここまでにしておきます。 それでと、回答No.9で私が言いたかったのは、window.addEventListenerを使うのなら、 ---- window.onload = init; ---- のところを、こうするようにと言うことでした。 ---- addEventListener("DOMContentLoaded", init); ---- いただいているチェックの処理での、window.addEventListenerは意味がありません。 ---- function validation_text(parts) { /* このpartsグループの、input=textを抽出 */ /* HTML要素を取得 */ let text = parts.getElementsByClassName('submit_button')[0]; /* バリデーション警告パーツを抽出 */ let validation = parts.getElementsByClassName('submit_button_validation')[0]; validation.style.display = 'none'; /* 例えばのチェック */ window.addEventListener('DOMContentLoaded', function() { let wao = document.getElementsByClassName('submit_button_validation'); const left = text.dataset.length - text.value.length; if (left >= 0) { /* ひとまずclassは複数配置できる形式なので、見つかった最初の1個目にアタッチ */ wao[0].innerHTML = "残り<span>" + v + "</span>文字入力できます。"; text.value.length === 0; } else { /* そのまま、2個目にアタッチ */ wao[1].innerHTML = "<span>" + v + "</span>文字超過しています。"; } }) }; ---- なぜなら、チェックのタイミングになってから、windowのDOMContentLoadedを追加してもイベントが発生しないからです。 回答No.10で文字数が表示されているか聞いたのはこういう理由です。
補足
Q.では、addEventListenerを使えばいいのだ、ではありません。 下手に使うとよくないことが起こります。 なぜなら、チェックのタイミングになってから、windowのDOMContentLoadedを追加してもイベントが発生しないからです。 A.アドバイスありがとうございます。サンプルコード試してみたところwindow.onloadを使えない理由が理解出来ました。 document.addEventListenerのように役割をそれぞれ分けて追加してあげる必要があるということですね。 文字数が表示されているか確認したのですが表示されていないので、dell_okさんがおっしゃるようにチェック時にイベントを追加しても意味のないようです。 DOMツリー構築完了後に/* カメラ画像をファイルアップロード時に非表示にする */const attach = document.querySelectorAll('.attach');コードを呼ぶ必要があり、window.onload = function() {} を使うようにしたのがきっかけですが、 シンプルに document.addEventListener を使う方が簡単なのではないかと指摘を頂いております。 名前とコメントの文字数をカウントする機能は window.onload を使わずにカメラ画像を画面表示後に呼ぶことは可能だと思われますでしょうか? <script> document.addEventListener('input', e => { if( !['name', 'message'].includes(e.target.id) ) return; const t = e.target, m = t.nextElementSibling, n = t.value.length - (t.dataset.length | 0), c = document.createElement('span'); c.append(Math.abs(n)); m.style.color = n>0?'red':'black'; m.replaceChildren(n>0?'':'残り', c, `文字${n>0?'超過してい':'入力でき'}ます。`); }); </script> </head> <body> <div> <h2>名前(name)<span>※必須</span></h2> <input type="text" name="name1" id="name" data-length="32" placeholder="未入力の場合は、匿名で表示されます" value=""> <div></div> </div> <div> <h2>コメント(comment)<span class="required">※必須</span></h2> <input type="text" name="name2" id="message" data-length="40" placeholder="荒らし行為や誹謗中傷や著作権の侵害はご遠慮ください"> <div></div> </div>
- dell_OK
- ベストアンサー率13% (766/5720)
・入力文字数でIF分岐するコードを囲う際に window.onload = function() {} が使われていた為、変更いたしました。 それで、今現在、入力時のリアルタイムで文字数など表示されていますか。
- dell_OK
- ベストアンサー率13% (766/5720)
・※window.onload = function() {} は動かない原因になりうるため window.addEventListener('DOMContentLoaded', function() {} を代用するように変更しております。 それは、ここではありません。 ---- /* 例えばのチェック */ window.addEventListener('DOMContentLoaded', function() { ---- ここのことです。 ---- window.onload = init; ----
補足
回答ありがとうございます、説明が抜けておりました申し訳ありません。 入力文字数でIF分岐するコードを囲う際に window.onload = function() {} が使われていた為、変更いたしました。 function validation_text(parts) { /* このpartsグループの、input=textを抽出 */ /* HTML要素を取得 */ let text=parts.getElementsByClassName('submit_button')[0]; /* バリデーション警告パーツを抽出 */ let validation=parts.getElementsByClassName('submit_button_validation')[0]; validation.style.display = 'none'; /* 例えばのチェック */ /* window.onload = function() {} を window.addEventListener('DOMContentLoaded', function() {} に変更 */ window.addEventListener('DOMContentLoaded', function() { let wao = document.getElementsByClassName('submit_button_validation'); const left = text.dataset.length-text.value.length; if (left >= 0) { /* ひとまずclassは複数配置できる形式なので、見つかった最初の1個目にアタッチ */ wao[0].innerHTML="残り<span>"+v+"</span>文字入力できます。"; text.value.length === 0; } else { /* そのまま、2個目にアタッチ */ wao[1].innerHTML="<span>"+v+"</span>文字超過しています。"; } }) };
お礼
申し訳ありません、データベースにアップロードファイルを格納する場合にサンプルコードを調べた際の参考サイトを提示しておりませんでした。 http://surferonwww.info/BlogEngine/?tag=/Upload
補足
「※最新コード」のURLが違うのか、ラジオボタンが type="feelingListbox" のままのようです。 A.回答ありがとうございます、gitで確認されているとのことで了解いたしました。ラジオボタンを変更したものと異なるリンクのものを修正しておりました申し訳ありません。 ※最新コード https://wandbox.org/permlink/H5perAX6gVLSavpt Q.ファイルのアップロードも名前やコメントやスタンプと同じところで処理すればいいので、FormDataに追加するのはそちらでやってください。 気になるのは fetch のURL /wp-admin/admin-ajax.php ですかね。 これでうまくいくのかどうか私の方では検証ができていません。 A.アドバイスありがとうございます、最新コードのnew-complete.phpの300行目から321行目までの下記コードをnew-complete.phpの251行目に移動いたしました。 現在のsingle-input.phpと参考サイトのFetch API でファイルをアップロードするの例に上がっているコードを比べたところ入力内容をチェックする項目はほぼ同じようでした。 ※修正コード https://wandbox.org/permlink/TyE4ReXNe92MEbIF // 送信データの準備 const formData = new FormData(); formData.append("uploadfile", uploadfile.files[0]); // ファイル内容を詰める const param = { method: "POST", body: formData } // アップロードする fetch("https://example.com/receive.php", param) .then((res)=>{//成功したら(then) ,responseのデータをコンソールに表示 return( res.json() ); }) .then((json)=>{ // 通信が成功した際の処理 }) .catch((error)=>{ // エラー処理 }); }); }); ファイル送信 有無が現在のsingle-input.phpにはなく、ファイルをディレクトリに保存する方法とデータベースに保存する方法で違いがあるようです。 削除や別途表示させる場合のことも考えて、データベースに保存する方法を取りたいのですが、Javascriptで書く必要がありそうで難しいのではないかと懸念しております… Fetch APIはネットワークエラーが起きた際に例外を投げ、それをキャッチできないとウェブアプリケーションの場合は画面が真っ白になるようで、fetch()・then ・then .catch によりエラーをキャッチするため、この文に合わせてデータベースに保存することになりそうです。 ※fetch APIを安全に使う方法 https://www.slideshare.net/i_Pride/fetch-api-255718218 ※入力内容をチェックする項目 1,ファイル容量 サイズ 2,ファイル形式 タイプ 3,ファイル送信 有無 4,MYMETYPE調べる +α 保存(ファイル名作成)