いつもお世話になります。
類似する質問も見つけられず、いろいろ試して悩んだ挙句、アプローチを変えてもう一度投稿することにしました。
発端は、下記のページです。
http://oshiete.goo.ne.jp/qa/8604578.html
問題は、phpmyadminからカラムまたはフィールドに入力したものは重複していればエラー表示されるのですが、PHPのフォームからMYSQLのデータベースに保存したもの(phpmyadmin上ではちゃんと登録されている)は重複とみなされず、エラーとして検出されません。
phpフォームからMYSQLのデータベースを呼び出してカラムまたはフィールド上に同じものがなければ保存、そうでなければエラー表示、といった形で重複させないプログラムを作成するつもりでした。
上記のページでご返信いただいたように、重複させないカラムにユニーク設定してみたのですが、問題は解決されませんでした。
文字コードが違うからと思ったのですが、MYSQL、PHPどちらもUTF-8で統一させています。
フォームからMYSQLへの保存時に問題があるのでは?と思うのですが、どのような形で修正すればうまくいくのか、わかりません。
どうか、知識の足りない私にご教授いただけないでしょうか?
PHPの設定とMYSQLへの登録のプログラムは下記の通りです。
PHP・・・5.4.19
XAMPP・・・1.8.2
phpmyadmin・・・4.0.4.1
データベース文字コード(UTF-8)
phpの文字コード(php.iniのdefault_characterをUTF-8に設定)
<?php
//データベースの接続設定
$DB_HOST = "localhost";
$DB_NAME = "○○";
$DB_USER = "○○";
$DB_PASS = "○○";
//データベースに接続する
$conn = mysql_connect($DB_HOST,$DB_USER,$DB_PASS) or die("接続エラー");
mysql_select_db($DB_NAME) or die("接続エラー");
//データベース登録前にメール送信する
$userID = $_POST['userID'];
$password = $_POST['password'];
$name = $_POST['name'];
$mail1 = $_POST['mail1'];
$userID = htmlspecialchars($userID);
$password = htmlspecialchars($password);
$name = htmlspecialchars($name);
$mail1 = htmlspecialchars($mail1);
$mail_sub = '登録を受け付けました。';
$mail_body = 'ご登録、誠にありがとうございました。';
$mail_body = html_entity_decode($mail_body,ENT_QUOTES,"UTF-8");
$mail_head = 'From:blowin@horae.dti.ne.jp';
mb_language('Japanese');
mb_internal_encoding("UTF-8");
mb_send_mail($mail1, $mail_sub, $mail_body,$mail_head);
?>
<?php
//デフォルトのタイムゾーンを日本に設定
date_default_timezone_set("Japan");
//フォーム情報をすべて受信
extract($_POST);
//そのまま代入する形ではエラーが起きるため、isset関数を使ってエラー回避する
if(isset($_POST['$userID'])){
$userID = cnv_dbstr($_POST['$userID']);
}
if(isset($_POST['$password'])){
$password = cnv_dbstr($_POST['$password']);
}
if(isset($_POST['$name'])){
$name = cnv_dbstr($_POST['$name']);
}
if(isset($_POST['$mail1'])){
$mail1 = cnv_dbstr($_POST['$mail1']);
}
//データを追加する
$sql = "INSERT IGNORE INTO touroku(userID,password,name,email,date)";
$sql .= "VALUES( " ;
$sql .= " ' " .$userID. " ', " ;
$sql .= " ' " .$password. " ', " ;
$sql .= " ' " .$name. " ', " ;
$sql .= " ' " .$mail1. " ', " ;
$sql .= " ' " .date("Y/m/d H:i:s") . " ' " ;
$sql .= " ) " ;
$res = mysql_query($sql,$conn) or die("データ追加エラー");
//SQLコマンド用の文字列に変換する関数
function cnv_dbstr($string){
//タグを無効にする
$string = htmlspecialchars($string);
//magic_quotes_gpcがOnの場合はエスケープを解除する
if(get_magic_quotes_gpc()){
$string = stripslashes($string);
}
//SQLコマンド用の文字列にエスケープする
$string = mysql_real_escape_string($string);
return $string;
}
header('location:./testkanryou.php');
exit;
?>
大変申し訳ありませんが、どうか、よろしくお願い申し上げます。
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
私なりに書き直してみました。
Pastebin.com - V8pST9nc
http://pastebin.com/V8pST9nc
もしかしてINSERT文に「IGNORE」をつけているのが原因じゃないですか…?このオプションはユニークキーがダブってたときにエラーを出さなくするためのものですね。
ご連絡ならびにご報告が大変遅くなって申し訳ありません。
まだ、ご回答にありましたページをしっかりと読み込めてないので、とりあえず書き直していただいたプログラムで動かしてみたところ、MYSQLへの保存とフォームからの入力時に重複を確認し、エラーとして表示することができました。
有難うございました。
INSERT文の「IGNORE」は、質問にあるページでそのようにしてみたら?と回答がありました。
性質は少し調べてある程度は理解してましたが、親切に教えていただいたこともありますし、藁をもすがる気持ちで試してみていました。
しかし、元々は「IGNORE」をつけていませんでしたので、今もそうですが、なぜ同じ文字列で登録されているにもかかわらず、重複と認識しなかったのか、また、var_dump()で中身が入っていなかったのか、理由がわかりません。
MYSQLには保存できる、でも重複として認識しない。保存する文字コードが違う可能性くらいしか思い浮かびませんでした。
書き直していただいたプログラムを有効に活用させていただくために、他のプログラムも手続き型からオブジェクト型にしようと思います。
繰り返しになってしましますが、本当に有難うございました。
No.1
- 回答日時:
気が遠くなるほど指摘すべき内容がありますが…(汗)さて、まず回答に入る前に前提としてもらいたい内容があるので、先に以下の記事をお読みください。
Qiita - $_GET, $_POSTなどを受け取る際の処理
http://qiita.com/mpyw/items/2f9955db1c02eeef43ea
Qiita - PHPでデータベースに接続するときのまとめ
http://qiita.com/mpyw/items/b00b72c5c95aac573b71
オブジェクト指向についての理解が足りない場合はこちらもどうぞ。今まさに書いている最中で未完成ですが…
Qiita - PHPオブジェクト指向入門
http://qiita.com/mpyw/items/41230bec5c02142ae691
手当たり次第になりますが、修正すべき個所を指摘していきます。
1.
全てのエラーメッセージを表示させる設定にしましょう。これを行っておかないとデバッグ作業の過程で大きな障壁になります。(既に設定済みの場合はスルーしてください)
2.
「mysql_*」に該当する関数は全て非推奨なので使わないでください。現在は「PDO」がよく用いられます。
3.
「or die("エラー")」だと原因が分からないので、mysql関数を使用するにしてもせめて「or die(mysql_error($conn))」としましょう。PDOを用いる場合は毎回こんな面倒なこと書かなくても「例外」という形で面倒見てくれてとてもラクです。
4.
POSTで値を受け取る際にはfilter_input関数を使いましょう。
5.
htmlspecialchars関数でエスケープするのはprintやechoで表示する直前にしましょう。あらかじめエスケープを行っておいてはいけません。hという名前のラッパー関数を作成しておくことを推奨します。
6.
SQL文中に安全に埋め込むためのエスケープ(mysql_real_escape_string)とHTMLとして安全に表示させるためのエスケープ(htmlspecilchars)は全く内容が異なります。「とりあえずどっちも行っておけば大丈夫」という横暴なことはせず、必要なものだけを必要なときに使用してください。
7.
extract($_POST) はやってはいけないとしてextract関数のマニュアルで警告されています。filter_input関数と可変変数への代入のループをうまく使って対応しましょう。
8.
PDOを使う場合、ユーザー入力をSQL文に埋め込む際にはプレースホルダを使用してください。PHPでエスケープしたものを変数展開して埋め込むことは非推奨とされています。
9.
現在の環境ではマジッククオート機能はほとんどOFFとなっていると思うので、stripslashesを通すかどうかのチェックはいらないと思います。…あ、PHP5.4ならOFFどころかもう削除されていてONにすることすらできませんね。
さて…直接の原因ですが…PDOに乗り換えたときに PDO::ATTR_ERRMODE オプションを PDO::ERRMODE_EXCEPTION にしておけばそれだけですぐ判明するので、かなり労力はかかると思いますがmysql関数からPDOへの書き換えを行ってみてください。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP PHP MySql 画像を取得 1 2022/06/04 14:05
- PHP PHPのエラーの解消法について教えて下さい。 1 2023/02/06 10:48
- PHP php ログイン 1 2022/11/01 00:24
- PHP 重複を防ぐ記述について教えて下さい。 3 2023/04/03 14:35
- Excel(エクセル) PHPプログラムをエクセルに張り付けると検索ボックスがでてくる! 3 2022/05/08 07:10
- PHP PHPでユーザー情報を入力して簡易ログイン機能をつくってみたのですが 1 2023/05/29 08:51
- PHP 入力した部分を表示させたまま(保持)するにはどうすれば良いでしょうか? 1 2023/01/25 11:14
- PHP htmlspecialcharsが機能していないです。 バグですか? 1 2022/04/05 01:22
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- PHP php テーブルが作成できない 1 2022/11/17 23:41
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Q&Aサイトを作成していてURLの...
-
データベースに存在するデータ...
-
MySQLへの接続
-
MySQLのINSERT時にたまに重複に...
-
【初歩】配列の格納データ数だ...
-
INSERT,DELETEを同時に
-
mysqlの命令文をPDOに書き換...
-
JAVA SQLServerException 列名 ...
-
PHP+SQLite でSELECT文のWHERE...
-
トランザクション処理
-
エクセルVBAについて
-
SQL文の実行に失敗しました???
-
VBAをつかってクエリの情報を抽...
-
PHPでMY SQLの連想配列をリンク...
-
PHP + MySQLを使用して詳細画面...
-
MySQLでshal()関数のエラーがで...
-
SQL文2つ実行
-
SQL文が実行できません
-
エラーの意味と対策
-
PHP+mysqlでSQL文に文字数制限...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
JAVA SQLServerException 列名 ...
-
Q&Aサイトを作成していてURLの...
-
<VB.NET>INSERT文でDBにデータ...
-
insert1つの処理でもトランザ...
-
Pro*Cの構文エラー
-
ResultSetインターフェイスでの...
-
データベースに存在するデータ...
-
PHP&MySQLでの文字列+数列の一...
-
VBA ACCESS SQL...
-
phpで複数の検索語を検索対象に...
-
like検索の複数キーワードで、...
-
MySQLのINSERT時にたまに重複に...
-
C# で発生したException.Messag...
-
PHP+PDO+MYSQL で実行されたSQ...
-
PHPのUndefined index や varia...
-
INSERT,DELETEを同時に
-
配列をループさせてUPDATE
-
VB.NET エラーになる箇...
-
php postgres Insert と updat...
-
C#でDBの特定列をUpdate
おすすめ情報