- ベストアンサー
フォームからMYSQLへの接続
- フォームからMYSQLへの接続とデータの書き込み・削除の方法について説明します。
- 番号か名前、電話番号を指定してデータ削除を行う方法について困っています。
- また、2重投稿を回避するためのheader関数の適切な位置についても教えてください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
名前や電話番号はユニークであることが前提ですが、それは大丈夫ですかね(MySQLのテーブル設計でUniqueにしていますか)。 $sql = "DELETE FROM address where no=$no or name='$name' or tel='$tel'"; print $sql; として、どういうSQL文になっているかを確認してください。おそらくは $no が空文字列なので(名前だけを入力したとしたら) DELETE FROM address where no= or name='入力した名前' or tel='' のようになっているハズです(SQL文としてダメ)。noが入力されていないときはwhereにnoを入れない(というか入力されたものだけをwhereで書く)ようにしてください(or で誤魔化すのは酷すぎます)。 あと、ネイティブなMySQL関数はすでに非推奨です。今から使うならPDOで(プレースホルダを使って)書いてください。何らかの事情でネイティブなMySQL関数を使うとしてもmysql_set_charsetでのcharset指定もなければmysql_real_escape_stringでエスケープもしていないのは異常です(セキュリティ的に「運用してはいけない」レベルのものになっています)。 >書く場所により「登録が完了しました。」「削除が完了しました。」の >メッセージが表示されなくなってしまいます。 ブラウザにメッセージを返したら、locationヘッダでの遷移は出来ません。locationヘッダで遷移した先のページでメッセージを表示してください。 #二重投稿は登録や削除に失敗するだけですよね。 #無理に回避する必要もないと思いますけど・・・。
その他の回答 (3)
- agunuz
- ベストアンサー率65% (288/438)
>「"DELETE FROM address where no=$no or where name='$name' or where tel='$tel'"」に >変えてみたのですがやはり結果は上手くいきません。 とりあえずはMySQLで「どういうSQL文になればいいのか」をちゃんと考えてください。 この例でいえば($no は整数値だとして) $where = array(); if ($no !== '') { $where[] = sprintf("(no = %d)", intval($no)); if ($name !== '') { $where[] = sprintf("(name = '%s')", mysql_real_escape_string($name)); if ($tel !== '') { $where[] = sprintf("(tel = '%s')", mysql_real_escape_string($tel)); if (count($where) === 0) { die('abort'); } // エラー処理 $result = mysql_query("DELETE FROM address where " . implode(' or ', $where), $con); くらいは最低限やらないとダメです(というか or で繋ぐというのもけっこうアバウトすぎる仕様だとは思いますけどね)。 >少し解りかけはじめたのに本当に残念です。 mysql_set_charsetやmysql_real_escape_stringまで覚えたのに・・・というなら解りますけど。まだ実用になるソースが書けないのですから、今のうちならいいでしょ。
お礼
シンプルな結果を出すのにも 構文は非常に複雑になってしまうのですね。 まだサンプルサイトの簡単な構文を見比べながら 勉強している状態で、mysql関数も非推奨になるといっても 練習ができただけでも良かったと思うことにします。 練習サイトや学習本などは最初は初歩からはじまっても 突然複雑で難しくなるものばかりで 思うように進歩がありません。 独学の場合、どうやったら効率の良い勉強ができ 継続できるかが一番の課題なのかもしれません。
- yambejp
- ベストアンサー率51% (3827/7415)
ポイントをいくつか とりあえず動くようにするのであれば DELETE構文自体はあっているので $noをシングルクォーテーションでくくるだけでいいかもしれません DELETE FROM address where no='$no' or name='$name' or tel='$tel' プレースホルダーについてはおいおい学習してください >少し解りかけはじめたのに本当に残念です。 mysql系の関数は多少の仕様変更でmysqli系の関数が引き継いでいます。 mysqli系の手続き型構文を学習すれば無駄にはなりません。 また要領さえつかめばmysqli系のオブジェクト型の構文にシフトできますし PDOに移行してもいいでしょう。 >あと「header("Location: {$_SERVER['PHP_SELF']}");」を使って まず$_SERVER['PHP_SELF']の使用はあまり勧められません $_SERVER['SCRIPT_NAME']に移行を検討してみてください また登録や失敗を表示することとheaderで飛ばすことは仕様が競合しています 飛ばす先をそれぞれseikou.htmとsippai.htmにするとか mypage.php?result=seikou、mypage.php?result=sippaiのようにして resultの値をみて表示をかえるなどで対応できます。 慣れてくればセッションで引き継いでもいいでしょう さて、本題ですがテストとしては問題ありませんが、不特定多数が 利用するサービスとしては番号を指定して削除をユーザーが自由にできる仕様は 他人の書き込みを第三者が無条件に消せてしまうので問題です。 ログインして、そのユーザーIDを元に文書IDごとに削除可能かどうか判断するようにするか その書き込みに対して削除パスワードを設定しておくなどシステムが必要になります ゆくゆくはそのあたりまで学習なさるといいでしょう
お礼
ご指導の通りシングルクォーテーションなども 試してみたのですが結局上手くいきませんでした。 完全に理解して構文を書いているわけではなく 適当に足したり、変えてみたりして 結果がでるかどうか試しているような状態なので なかなか進歩がないのかもしれません。 とにかくアドバイス感謝しています。 ありがとうございました!
以下の記事をもって回答とさせていただきます。ここで回答すべきことはほぼ全て網羅しているので。 Qiita - PHPでデータベースに接続するときのまとめ http://qiita.com/mpyw/items/b00b72c5c95aac573b71 2重投稿回避については、ユニークキー制約をつけるだけで問題解決しますよね。
お礼
ありがとうございます! リンク先ざっと見させていただきました。 まだ全く理解できないようなレベルなので 今課題はあきらめることにしました。 1年後くらいに「あ~こうだったんだ!」思えるように なれることを期待します。
お礼
MYSQLはまだほんの少し目を通すくらいしか勉強していないため 詳しい設定方法などはわからないのですが XamppのphpMyAdminから確認すると ユニークの設定はno, neme, tel,とも自動にされているようです。 MYSQLでは「DELETE FROM address where no=$no or name='$name' or tel='$tel'」の文で 該当されるデータが上手く削除されるので良いと思って使ってみたのですが あまり良くないのですね。 「"DELETE FROM address where no=$no or where name='$name' or where tel='$tel'"」に 変えてみたのですがやはり結果は上手くいきません。 mysql_setなどは非推奨になり、今更勉強する意味は なくなってしまうようでせっかく 少し解りかけはじめたのに本当に残念です。 プレースホルダというのは 少し前に勉強して全く理解できなかったオブジェクト指向を使うようで まだPHP自体を少ししか理解できていないレベルの私には 別の簡単なことから 手を付けていったほうが良いのかもしれません。 とにかくありがとうございました。