フォームからの入力で登録ボタンを押して
MYSQLへデータの書き込み、そして削除ボタンを押して
データを削除するという勉強をしています。
削除の場合は、番号か名前、電話番号のいずれかを入力して
削除ボタンを押せば該当するデータが削除されるようにしたいのですが
番号指定以外の名前指定や電話番号指定での削除ができません。
「DELETE FROM address where no=$no or name='$name' or tel='$tel'」の
書き方に問題があるようですが
どのようにしたらよいのでしょうか?
----------------------------------------------
<html>
<body>
<form action="" method="post">
番号:<br><input type="text" name="no"><br>
氏名:<br><input type="text" name="name"><br>
電話番号:<br><input type="text" name="tel"><br><br>
<input type="submit" value="登録" name="submit">
<input type="submit" value="削除" name="submit">
</form>
<?php
error_reporting(1);
$con = mysql_connect("127.0.0.1", "root", "");
if(!$con){
exit("データベースに接続できませんでした。");
}
$result = mysql_select_db("test", $con);
if(!$result){
exit("データベースを選択できませんでした。");
}
$no = $_POST["no"];
$name = $_POST["name"];
$tel = $_POST["tel"];
$submit = $_POST["submit"];
if($no != null){
if($submit == "登録"){
$result = mysql_query("INSERT INTO address(no, name, tel)
VALUES ('$no', '$name', '$tel')", $con);
if($result){
echo "<p>登録が完了しました。<br>";
}else{
echo "<p>登録失敗</p>";
}
}elseif($submit == "削除"){
$result = mysql_query("DELETE FROM address where no=$no or name='$name' or tel='$tel'", $con);
if($result){
echo "<p>削除が完了しました。<br>";
}else{
echo "<p>削除失敗</p>";
}
}
}
?>
</body>
</html>
----------------------------------------------
あと「header("Location: {$_SERVER['PHP_SELF']}");」を使って
2重投稿を回避したいのですが
書く場所により「登録が完了しました。」「削除が完了しました。」の
メッセージが表示されなくなってしまいます。
どこに記入したらよいのでしょうか?
よろしくお願いいたします。
No.1ベストアンサー
- 回答日時:
名前や電話番号はユニークであることが前提ですが、それは大丈夫ですかね(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ヘッダで遷移した先のページでメッセージを表示してください。
#二重投稿は登録や削除に失敗するだけですよね。
#無理に回避する必要もないと思いますけど・・・。
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自体を少ししか理解できていないレベルの私には
別の簡単なことから
手を付けていったほうが良いのかもしれません。
とにかくありがとうございました。
No.4
- 回答日時:
>「"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関数も非推奨になるといっても
練習ができただけでも良かったと思うことにします。
練習サイトや学習本などは最初は初歩からはじまっても
突然複雑で難しくなるものばかりで
思うように進歩がありません。
独学の場合、どうやったら効率の良い勉強ができ
継続できるかが一番の課題なのかもしれません。
No.3
- 回答日時:
ポイントをいくつか
とりあえず動くようにするのであれば
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ごとに削除可能かどうか判断するようにするか
その書き込みに対して削除パスワードを設定しておくなどシステムが必要になります
ゆくゆくはそのあたりまで学習なさるといいでしょう
ご指導の通りシングルクォーテーションなども
試してみたのですが結局上手くいきませんでした。
完全に理解して構文を書いているわけではなく
適当に足したり、変えてみたりして
結果がでるかどうか試しているような状態なので
なかなか進歩がないのかもしれません。
とにかくアドバイス感謝しています。
ありがとうございました!
No.2
- 回答日時:
以下の記事をもって回答とさせていただきます。
ここで回答すべきことはほぼ全て網羅しているので。Qiita - PHPでデータベースに接続するときのまとめ
http://qiita.com/mpyw/items/b00b72c5c95aac573b71
2重投稿回避については、ユニークキー制約をつけるだけで問題解決しますよね。
ありがとうございます!
リンク先ざっと見させていただきました。
まだ全く理解できないようなレベルなので
今課題はあきらめることにしました。
1年後くらいに「あ~こうだったんだ!」思えるように
なれることを期待します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
プログラミングC++のmapについて
-
サブフォルダ内の全てのテキス...
-
VBA で、スペースを含むファイ...
-
PHPからデータベースの該当行を...
-
CakePHP テーブル名カラム名の...
-
イタリア人がCatherineと聞いた...
-
Flaskでサーバー立ち上げに関して
-
フォームからMYSQLへの接続
-
HTMLで前の画面に戻る時、入力...
-
テキストリンクをPOST送信したい
-
PHPでクリックするたびに変数を...
-
チェックボックスを用い、MySQL...
-
laravelを利用してコントロール...
-
フォーム送信後の更新ボタンで...
-
phpで、フォームのラジオボタン...
-
<input type="hidden" >で配列...
-
PHPでフォームデータをサンクス...
-
ラジオボタンをsessionで使いたい
-
検索後にチェックボックスのON/...
-
$_POSTを連想配列で取得したい!!
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Flaskでサーバー立ち上げに関して
-
VBA で、スペースを含むファイ...
-
POSTの項目に追加
-
phpで変数を使ってcopyできない
-
PHPからHTMLへの変数の受け...
-
foreachがうまく動かない
-
ファイル名を変更してアップロ...
-
MySQL,PHPのリロードによる二重...
-
$_SESSIONに渡した後はそのまま...
-
引数の参照について
-
ログイン パスワード変更のプ...
-
Smartyのforeachのnameに変数を...
-
PHP等を用いて在庫数を表示・管...
-
formでのチェックボックスのnam...
-
アップロードファイル名の文字化け
-
検索結果の出力先を違うフレー...
-
プログラムの流れの確認で・・
-
テキストボックスの値を取得したい
-
プルダウンでデータ送信後、値...
-
if文のなかで
おすすめ情報