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

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

詳細はこちら
PHP

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

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

1回答

1371閲覧

jsのpromptで入力された値を、AJAXを用いPHPの変数に格納したい

MakotoIshizawa

総合スコア32

PHP

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

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2019/12/06 11:06

編集2019/12/09 10:45

ある課題に取り組んでいて簡易掲示板を作っています。
テキスト保存のものを作った後、MySQL保存に変えたものを作っています。
php5.2.4(指定による)
mysqlのサーバー情報は伏せてあります。

jsでパスワードの入力を求め、その値をPHP側の check_password に格納したいです。
jsで変数check_password を作り、その変数内でpromptを書いています。(これが正しいのかどうかも判断出来ません)(107行目から)
動作としては、「本当に削除しますか」と表示し「yes」ならパスワードの入力を求めます。
そこまでは動作出来ています。(編集ではすぐパスワードを求めます)
その後パスワードをPHPに渡すところが出来ません。

jsから直接値を渡せないこと、AJAXを使えばなんとか出来そうと言うところまでは来ましたが、どの様に書けば望んだ動作がなされるのかわかりません。
色々探し回りましたが、まだ理解が追いついていません。
どの様に書けばよろしいでしょうか?

渡せたかどうかを見るためにcheck_passwordをvar_dumpしています。(154行目)

php

1<?php 2ini_set( "display_errors", 1 ); 3error_reporting( E_ALL ); 4//変数の定義 5$name = filter_input( INPUT_POST, "name" ); //投稿者の名前 6$comment = filter_input( INPUT_POST, "comment" ); //投稿したコメント 7$delete_no = filter_input( INPUT_POST, "delete_no" ); //削除指定番号 8$edit_no = filter_input( INPUT_POST, "edit_no" ); //編集指定番号 9$edit_decision = filter_input( INPUT_POST, "edit_decision" ); //投稿と編集の判別用のhidden送信 10$password = filter_input( INPUT_POST, "password" ); //送信するpassword 11$check_password = filter_input( INPUT_POST, "check_password" ); //照合するパスワード 12$date = date( "Y-m-d H:i:s" ); //投稿日時 13$replace_search = array( "\r\n", "\r", "\n" ); //置き換えのための改行コードの検索 14$replace = array( "<<改行win>>", "<<改行mac>>", "<<改行unix>>" ); //改行コードを置き換える文字 15$replace_name = str_replace( $replace_search, $replace, $name ); //改行を置き換えた名前 16$replace_comment = str_replace( $replace_search, $replace, $comment ); //改行を置き換えられたコメント 17$nothing_message = "";//番号がない時のmessageの初期化 18//MySQL接続情報 19$servername = ""; 20$username = ""; 21$serverpassword = ""; 22$dbname = ""; 23//編集時の表示用名前とコメントの初期化 24$edit_name = ""; 25$edit_comment = ""; 26$edit_num = ""; 27$decision_no = ""; 28//messageの初期化 29$edit_message = ""; 30$edit_nothing_message = ""; 31$num_message = ""; 32$delete_message = ""; 33//書き込み内容のsql文 34$insert_sql = "INSERT INTO toko( 35name, comment, date, password 36) VALUES ( 37'$replace_name', '$replace_comment', '$date', '$password' 38)"; 39 40//データベースに接続 41try { 42 $db = new PDO( "mysql:dbname=$dbname;host=$servername;charset=utf8mb4", $username, $serverpassword, [ 43 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 44 PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, 45 ] ); 46 //投稿機能 47 if ( !empty( $name ) && !empty( $comment ) && empty( $edit_decision ) ) { 48 $insert = $db->query( $insert_sql ); //書き込みsql実行 49 //リロードし二重書き込み防止 50 header( 'Location: keijiban_mysql.php', true, 303 ); 51 exit; 52 } 53 //削除機能 54 if ( !empty( $delete_no ) ) { 55 //削除指定番号の行のデータ取得のsql文 56 $delete_select = $db->prepare( "SELECT * FROM toko WHERE num = '$delete_no'" ); 57 $delete_select->execute(); //実行 58 $delete_select = $delete_select->fetch( PDO::FETCH_ASSOC ); //データ取得 59 $delete_num = $delete_select['num']; 60 if( !empty( $delete_num ) ){ 61 $delete_sql = "DELETE FROM toko WHERE num='$delete_no'"; 62 $delete = $db->query( $delete_sql ); 63 $delete_message = '削除されました'; 64 }else{ 65 $delete_message = "<span class='akaji'>".'該当する番号はありません'."</span>"; 66 } 67 } 68 //編集番号指定 69 if ( !empty( $edit_no ) ) { 70 $decision_no = $edit_no;//判定用の変数定義 //編集指定番号の行のデータ取得のsql文 71 $edit_select = $db->prepare( "SELECT * FROM toko WHERE num = '$edit_no'" ); 72 $edit_select->execute(); //実行 73 $edit_select = $edit_select->fetch( PDO::FETCH_ASSOC ); //データ取得 74 $edit_name = $edit_select[ 'name' ]; //テーブル内の取り出したnameの定義 75 $edit_comment = $edit_select[ 'comment' ]; //テーブル内の取り出したcommentの定義 76 $edit_num = $edit_select[ 'num' ];//テーブル内の取り出したnumの定義 77 if ( !empty( $edit_num ) ){ 78 $edit_message = $edit_no . '番の投稿を編集します'; 79 } else { 80 $edit_nothing_message = "<span class='akaji'>".'該当する番号はありません'."</span>"; 81 } 82 } 83 84 85 //編集機能 86 if ( !empty( $name ) && !empty( $comment ) && !empty( $edit_decision ) ) { //名前とコメントと編集判定が送信されたら 87 88 //編集のSQL文 89$update = "UPDATE toko SET name = :name, comment = :comment WHERE num = :num"; 90 $update = $db->prepare($update); 91 $params = array(':name' => $replace_name, ':comment' => $replace_comment, ':num' => $edit_decision); 92 $update->execute($params); 93 } 94} catch ( PDOException $e ) { 95 print( "エラー:" . $e->getmessage() ); 96 die(); 97 //リロードし二重書き込み防止 98 header( 'Location: keijiban_mysql.php', true, 303 ); 99 exit; 100} 101?> 102<!doctype html> 103<html lang="ja"> 104<head> 105<meta charset="utf-8"> 106<title>簡易掲示板MySQL保存版</title> 107<script> 108 //削除時の確認 109 window.addEventListener('DOMContentLoaded', function(){ 110 document.querySelector('#delete_button').addEventListener('click',function(e){ 111 if(confirm("本当に削除しますか?")){//本当に削除しますか?と表示しyes,noの選択肢を出す 112 var check_password = prompt("パスワードを入力してください");//yesならパスワード入力を求める 113 }else{ 114 alert('キャンセルされました');//「キャンセルされました」 と表示 115 e.preventDefault();//キャンセルの実行(defaultの動作を妨害) 116 } 117 }); 118 }); 119 120//編集と削除時のパスワードの入力 121 window.addEventListener('DOMContentLoaded', function(){ 122 document.querySelector('#edit_button').addEventListener('click',function(e){ 123 if(!prompt("パスワードを入力してください")){ 124 alert('キャンセルされました'); 125 e.preventDefault(); 126 } 127 }); 128 }); 129 130//PHPへ値を渡す 131 $.ajax ( { 132 type: 'POST', 133 url: 'keijiban_mysql.php', 134 data: { 135 'check_password' : check_password, 136 }, 137 success: function(data) { 138 alert(data); 139 } 140 }); 141</script> 142<style> 143.akaji { 144 color : red; 145} 146.komoji { 147 font-size: 0.8em; 148} 149</style> 150</head> 151<body> 152<?php 153 var_dump($check_password); 154 //XSS対策 155 function h( $str ) { 156 return nl2br( htmlspecialchars( $str, ENT_QUOTES, 'UTF-8' ) ); 157 } 158//改行の置き換え 159$replace_seach = array( "<<改行win>>", "<<改行mac>>", "<<改行unix>>" ); //改行の置き換え文字の検索 160$replace = array( "\r\n", "\r", "\n" ); //改行コードへの置き換え 161 162?> 163<!--投稿フォーム--> 164<form method="post" > 165 <label for="name">お名前<span class="akaji">【必須】</span></label> 166 <?php 167 if ( !empty( $edit_no ) ) { 168 echo $edit_message; 169 } 170 ?> 171 <br> 172 <input type="hidden" name="edit_decision" value="<?php 173 echo $decision_no; 174 ?>" > 175 <input type="text" name="name" id="name" required="required" value="<?php 176 echo $edit_name; 177 ?>" > 178 <br> 179 <label for="comment">コメント<span class="akaji">【必須】</span></label><br> 180 <textarea name="comment" cols="30" rows="3" id="comment" required="required"> 181 <?php 182 echo $edit_comment; 183 ?> 184 </textarea><br> 185 <label for="possword">パスワード<span class="akaji">【必須】</span></label><br> 186 <input type="password" name="password" id="password" required="required"> 187 <br> 188 <input type="submit" value=<?php 189 if(!empty( $edit_no ) ){ 190 echo '編集'; 191 } else { 192 echo '投稿'; 193 } 194 ?> > 195</form> 196<br> 197<!--削除番号指定用フォーム--> 198<form method="post" name="delete"> 199 <label for="delete_no">削除対象番号</label> 200 <?php 201 if( !empty( $delete_no ) ) { 202 echo $delete_message; 203 } 204 ?> 205 <br> 206 <input type="number" name="delete_no" id="delete_no" required="required"><br> 207 <input type="submit" value="削除" name="btn" id="delete_button"> 208</form> 209 <br> 210<!--編集番号指定用フォーム--> 211<form method="post"> 212 <label for="edit_no">編集対象番号(半角)</label> 213 <?php 214 if ( !empty( $edit_no ) ) { 215 echo $edit_nothing_message; 216 } 217 ?> 218 <br> 219 <input type="number" name="edit_no" id="edit_no" required="required"><br> 220 <input type="submit" value="送信" id="edit_button"> 221</form> 222<br> 223 224<?php 225//投稿内容の表示 226 try { 227 //テーブルの行数取得 228 $sql = 'select count(*) from toko'; 229 $count = $db->query( $sql ); 230 $count = $count->fetchColumn(); 231 $select = "SELECT * FROM toko"; //テーブルデータの取得のクエリ 232 $select = $db->query( $select ); //クエリの実行 233//投稿がない場合「投稿はまだありません」と表示する 234 if ( $count == 0 ) {//行数が0だったら 235 echo "<p>投稿はまだありません</p>";//投稿はまだありませんと表示する 236 } else {//その他の場合 237 foreach ( $select as $row ) { //ループして表示 238 echo "<span class='komoji'>No</span>:" . h( $row[ 'num' ] ) . "&emsp;&emsp;" . 239 "<span class='komoji'>名前</span>: " . h( $row[ 'name' ] ) . "<br>" . 240 h( $row[ 'comment' ] ) . "<br>" . 241 "<span class='komoji'>".h( $row[ 'date' ] ) . "</span><br>"; 242 } 243 } 244 245 } catch ( PDOException $e ) { 246   print( "表示エラー:" . $e->getmessage() ); 247   die(); 248 } 249 250?> 251</body> 252</html> 253

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

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

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

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

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

m.ts10806

2019/12/06 11:56

インデントはきちんとつけましょう。 申し訳ないですが読む気しません
m.ts10806

2019/12/06 11:57

あともう少しコードを最低限再現できるくらいにされたほうが問題切り分けしやすくなるかと思います。
MakotoIshizawa

2019/12/06 23:20

ありがとうございます。 インデントをきちんとつけるところから始めようと思います。
guest

回答1

0

ベストアンサー

passeordでいいんか?
posswordもあるけど?
タイプミスや文法エラーを検出できるエディタを活用することを強くおすすめしたい。
使えない場合は、気になる箇所を文字列検索してタイプミスを目視で発見できるよう頑張る。
どんなエディタがいいかは、色んな人がいろんなところで記事にしているから自分で探すこと。
(自分に合う合わないもあるから、いくつか並行して試してみるとヨサゲ)

そもそも、delete_noやedit_noを送信する削除/編集フォームに、
なぜpasswordを送信するinput要素を置かないのか。
かつ、
なぜpasswordだけajax利用で送信しようとしているけど、
phpでの処理待受できる構造になってないので、
この場面ならajaxをあやふやに使うんじゃなくて、
そもそも、delete_noやedit_noを送信するフォームに、
passwordを送信するinput要素を置いてみるのを試すこと。
ajaxは止める。

もしかして
delete_noやedit_noを送信する削除/編集フォーム送信後に、
確認画面を作ろうとしている?
だとするとそれをajax駆使して別途パスワード送信するのはピンとこない。
すべての処理を一つのphpに封じ込めて作ろうとして
処理の分岐や構造がわからなくなって破綻し始めているように見える。
一度、処理ごとにhtmlとphpを全部バラして作ってみて、
それがうまく機能するようになってからまとめ直すやり方を
おすすめしたい。
例えば、
▼投稿フォーム兼投稿データ表示画面
▼投稿結果表示画面(からリダイレクトして投稿フォーム兼投稿データ表示画面に戻るとか)
▼削除フォーム画面
▼削除確認画面
▼更新フォーム画面
▼更新確認画面
くらいに機能単位で分割して組み立てれば、他の処理に惑わされず作りたい機能に集中できるはず。

teratailにいろんな回答者が居て、
これまで質問者さんが掲げた質問を表層的に捉えて簡単に回答して、
それを全部取り入れると「船頭多くして船山に登る」になってしまっているのかもしれない。
取り入れるかどうか、組み込むかどうか、設計書レベルから見直しすることを勧めたい。


php

1$insert_sql = "INSERT INTO toko( 2name, comment, date, password 3) VALUES ( 4'$replace_name', '$replace_comment', '$date', '$password' 5)";

外部から与えられる値を格納した変数を、
直接SQL文内で展開するのは、
SQLインジェクションの問題を孕むから止めような。
そして、複数行に渡るSQLを記述するなら、
ヒアドキュメント構文使おうぜ。

php

1$insert_sql = <<<EOT 2INSERT INTO toko( 3 name, comment, date, password 4) VALUES ( 5 :replace_name, :replace_comment, :date, :password 6); 7EOT;

php

1$edit_select = $db->prepare( "SELECT * FROM toko WHERE num = '$edit_no'" );

ここも、せっかくのprepareが台無し。

php

1$edit_select = $db->prepare( "SELECT * FROM toko WHERE num = :edit_no" );

とかする。
もちろん、bindValue()でバインドしてからexecute()すること。


php

1 $delete_select = $delete_select->fetch( PDO::FETCH_ASSOC ); //データ取得 2 $delete_num = $delete_select['num']; 3 if( !empty( $delete_num ) ){

この箇所、fetch()失敗していたら$delete_selectはFALSEになるよね。
$delete_selectがFALSEかどうかを判定し、その後に$delete_select['num']を判定するようにしたいところ。


SELECT文以外のSQLを実行する箇所、トランザクション処理していないの、こわい。
簡易掲示板だから、扱うテーブルが一つで、データ構造の主従関係とか想定しなくていいから、
この場では大した問題にならないかもしれないけど、
複数のテーブルを扱うような場面に遭遇したときにテーブルAに書き込んでテーブルBに書き込むときにエラーが出たりしたときは、
一連の処理を「なかったこと」にすることも必要になる。
そのための練習も兼ねてbeginTransaction()とか駆使してみるといいよ。

tryブロックの外で$insert_sqlだけ定義して、
他のSQL文はifブロック内の局所変数っていうあべこべさ。
そして、
後の処理で使うかどうかわからないけど冒頭で片っ端からPOST受信データを変数に突っ込んでるのも気になる。
処理の分岐判定に必要なパラメータだけ最初に解釈して、
更新処理なら更新処理に必要なもの、
削除処理なら削除処理に必要なものっていうふうに局所的にやったほうが
全体の見通し風通しが良くなる気がする。

投稿2019/12/06 12:22

編集2019/12/06 13:17
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

MakotoIshizawa

2019/12/06 23:35

凄くたくさんのアドバイスありがとうございます。 質問文も悪かったなあと思いました。 ある課題をやっているのですが、 「編集削除の際に、パスワードの入力を求める。具体的にはパスワード入力ができるようにしたformを表示し、入力させる。」というのがありまして、jsかなと思いやって見て、せっかく手を付けたから出来したいと思って取り組んでしました。 やはりinputを置くのが妥当なのでしょうか。 同様の課題でテキスト保存版で同じことをしていますが、そちらではPHPでやってみました。 受け渡し後の処理についてはまだ書いていない状態でした。 エディターはDWを使っていますが、タイプミスをしてよく躓いてしまっています。 諸々のアドバイスを参考に修正して、全体を見直してみたいと思います。 まずは、インデントをちゃんと付けるところからスタートしようと思います。 その後に、諸々のご指摘の箇所を修正していきます。 bindValue()とかヒアドキュメント構文とかまだ未知の単語なので、調べて対処します。 大変詳細に渡る御指摘頂きまして本当に助かります。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問