質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

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

Q&A

解決済

2回答

5685閲覧

重複データをはじいて、メッセージを表示したい

YukaSaku

総合スコア52

PHP

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

0グッド

0クリップ

投稿2017/05/10 16:25

編集2017/05/10 17:48

フォーム登録画面で、もし同じユーザーネームが登録されたら、”○○ is already exist.” と表示させたいです。現在は、DBのユーザーネームをuniqueにして、ただ単にクエリーエラーにさせてるだけです。
それをきちんとプログラム内で、重複データ用のエラーを表示させたいです。

現在の動くプログラムはこんな感じです。

php

1<?php 2/* Program name: register.php 3 * Description: Program displays the blank form and checks 4 * all the form fields for blank fields. 5 */ 6 7 8ini_set("display_errors","on"); 9error_reporting(E_ALL | E_STRICT); 10ini_set("include_path","./includes"); 11include("dbinfo.inc"); 12 13if(isset($_POST['submitted']) and $_POST['submitted'] == "yes") 14{ 15 16 foreach($_POST as $field => $value) 17 { 18 if(empty($value)) 19 { 20 $blank_data[] = $field; 21 } 22 else 23 { 24 $good_data[$field] = strip_tags(trim($value)); 25 } 26 } 27 if(@sizeof($blank_data) > 0) 28 { 29 $message = "<p style='color: red; margin-bottom: 0; 30 font-weight: bold'> 31 You didn't fill in one or more required fields. 32 You must enter: 33 <ul style='color: red; margin-top: 0; 34 list-style: none' >"; 35 /* display list of missing information */ 36 foreach($blank_data as $value) 37 { 38 $message .= "<li>$value</li>"; 39 } 40 $message .= "</ul>"; 41 //extract($good_data); 42 echo $message; 43 include("form.inc"); 44 exit(); 45 } 46 foreach($_POST as $field => $value) 47 { 48 if(!empty($value)) 49 { 50 //validations 51 $name_patt = "/^[A-Za-z0-9' -]{1,15}$/"; 52 $email_patt = "/^.+@.+\\..+$/"; 53 $passwd_patt = "/^[A-Za-z0-9' -]{1,15}$/"; 54 55 $field = htmlspecialchars($field, ENT_QUOTES); 56 $value = htmlspecialchars($value, ENT_QUOTES); 57 58 if(preg_match("/username/i",$field)) 59 { 60 if(!preg_match($name_patt,$value)) 61 { 62 $error_array[] = "$value is not a valid Username"; 63 } 64 } 65 if(preg_match("/email/i",$field)) 66 { 67 if(!preg_match($email_patt,$value)) 68 { 69 $error_array[] = "$value is not a valid Email"; 70 } 71 } 72 73 if(preg_match("/password/i",$field)) 74 { 75 if(!preg_match($passwd_patt,$value)) 76 { 77 $error_array[] = "$value is not a valid password"; 78 } 79 } 80 } 81 } 82 if(@sizeof($error_array) > 0) 83 { 84 $message = "<ul style='color: red; list-style: none' >"; 85 foreach($error_array as $value) 86 { 87 $message .= "<li>$value</li>"; 88 } 89 $message .= "</ul>"; 90 echo $message; 91 @extract($clean_data); 92 include("form.inc"); 93 exit(); 94 } 95 else 96 { 97 $cxn = mysqli_connect($host,$user,$passwd,$dbname) 98 or die("Couldn't connect to server"); 99 //foreach((array)$clean_data as $field => $value) 100 $clean_data = array(); 101 foreach($_POST as $field => $value) 102 { 103 $clean_data[$field] = mysqli_real_escape_string($cxn,$value); 104 } 105 $date = date("Y-m-d H:i:s"); 106 //echo date("Y/m/d H:i:s",$date); 107 //$sql = "INSERT INTO CustomerPhone (last_name,first_name,middle_name,phone) 108 //VALUES ('$clean_data[last_name]','$clean_data[first_name]', 109 // '$clean_data[middle_name]','$clean_data[phone]')"; 110 ?> 111 <form method="post"> 112 <input type="hidden" name='$field' value="<?php echo htmlspecialchars($good_data['value']); ?>"> 113 <input type="hidden" name="date" value="<?php echo $date; ?>"> 114 </form> 115 116 <?php 117 //$status = "none"; 118 /* loop that displays the form */ 119 $sql = "INSERT INTO login (username,email,password,date) 120 VALUES ('".$clean_data['username']."','".$clean_data['email']."', 121 '".$clean_data['password']."','$date')"; 122 123 124 125//echo $clean_data['username']; 126 $result = mysqli_query($cxn,$sql) 127 or die("Couldn't execute query"); 128 $signUpMessage = 'Registered. Your Username is '.$clean_data['username'].' Password is'.$clean_data['password'].' '; 129 echo $signUpMessage; 130 include("stored.inc"); 131 } 132} 133else 134{ 135 include("form.inc"); 136} 137?>

そして、エラーメッセージを出すために$clean_dataをinsert into したあとに、この条件文を入れました。

php

1// userテーブルからemail項目を条件に1件取得するSQL文 2$sql = "select * from login where username = :username"; 3// SQL発行準備 4$stmt = $cxn->prepare($sql); 5// SQL発行。条件のusernameは、引数$usernameの値。 6$stmt->execute(array(":username" => $username)); 7// loginテーブルから1件データ取得 8$login = $stmt->fetch(); 9// $usernameが存在していればtrue、そうでなければfalseを返す 10return $login ? true : false; 11 if ($login == "true"){ 12 echo ''.$username.' is already exist.' ; 13 }

そして、DBに既に存在するユーザーネームを打ち込むと、

Fatal error: Uncaught Error: Call to a member function execute() on boolean in /home/vol14_5/ihostfull.com/uoolo_19138640/htdocs/PHP/Ex5/E5/register.php:128 Stack trace: #0 {main} thrown in /home/vol14_5/ihostfull.com/uoolo_19138640/htdocs/PHP/Ex5/E5/register.php on line 128

と表示されます。

どのようにしたらいいでしょうか?

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

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

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

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

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

guest

回答2

0

ベストアンサー

現在の動くプログラム

では mysqliモジュールを使用していますが、

$clean_dataをinsert into したあとに

追加したプログラムは PDOモジュールを使用しているかのような文になってることが、
エラーの原因です。


それ以前に、今、試みている方法では正しく

重複データ用のエラーを表示

することはできません。

$clean_dataをinsert into したあと

select * from loginを実行すると必ず1件以上のデータが存在するため、
常にエラーメッセージが表示されることになるからです。

代わりに、

DBのユーザーネームをunique

のままにした上で、以下のようにすると良いでしょう。

php

1 // IGNORE キーワードを追加 2 $sql = "INSERT IGNORE INTO login (username,email,password,date) 3 VALUES ('".$clean_data['username']."','".$clean_data['email']."', 4 '".$clean_data['password']."','$date')"; 5 6 $result = mysqli_query($cxn, $sql) 7 or die("Couldn't execute query"); 8 9 $affectedRows = mysqli_affected_rows($cxn); 10 if ($affectedRows === 1) { 11 $signUpMessage = 'Registered. Your Username is '.$clean_data['username'].' Password is'.$clean_data['password'].' '; 12 echo $signUpMessage; 13 } else if ($affectedRows === 0) { 14 echo $clean_data['username'] . ' is already exist.' ; 15 } else { 16 die('Something is wrong...'); 17 18 }

https://dev.mysql.com/doc/refman/5.6/ja/insert.html

IGNORE キーワードを使用した場合、(中略)重複キーエラーは生成しません。

http://php.net/manual/ja/mysqli.affected-rows.php

直前の MySQL の操作で変更された行の数を得る

投稿2017/05/10 23:43

KiyoshiMotoki

総合スコア4791

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

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

YukaSaku

2017/05/11 18:03 編集

とてもわかりやすい説明とサンプルをありがとうございます。解決しました。 そうなんです、PDOとmysqliが頭の中でかなり混乱しています。 ちゃんと分けて考えられるよう、勉強します。
guest

0

エラーメッセージを読んでみてください。register.php の 128 行目で boolean の execute を呼んでいるが、そんなものはないと書いています。

PDO::prepare

返り値 ¶

もしデータベースサーバーが正常に文を準備する場合、 PDO::prepare() は PDOStatement オブジェクトを返します。 もしデータベースサーバーが文を準備できなかった場合、 PDO::prepare() は FALSE を返すか PDOException を発行します (エラー処理 の方法に依存します)。

投稿2017/05/10 22:45

編集2017/05/10 22:45
Zuishin

総合スコア28656

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

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

YukaSaku

2017/05/11 18:02

ありがとうございます。PDO、もっと詳しく勉強します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問