メールアドレスの重複チェックについて
解決済
回答 2
投稿
- 評価
- クリップ 1
- VIEW 3,826
下記コードで、アドレスの重複チェックを表示することができました。
DBでuserdataというテーブルにemailというカラムがあり、test@testという値が格納されてます。
<?php
$dsn = 'mysql:dbname=test;host=localhost;charset=utf8';
$user = 'root';
$password = '';
try{
$dbh = new PDO($dsn, $user, $password);
$dbh->query('SET NAMES sjis');
$sql = 'select * from userdata';
foreach ($dbh->query($sql) as $row) {
if($row['email'] == $_POST['email1']){
echo ($_POST['email1'] ."は既に登録されています");
}
}
}catch (PDOException $e){
print('Error:'.$e->getMessage());
die();
}
$dbh = null;
?>
<tr>
<td>E-mail</td>
<td colspan="2"><input type="email" name="email1" maxlength="50" size="46" placeholder="info@example.com" ></td>
<td></td>
</tr>
とりあえず正常に動作するかのテストなのでブラウザの一番上に表示されている状態ですが
本当は下記のところに表示させたいのです。
<tr>
<td>E-mail</td>
<td colspan="2"><input type="email" name="email1" maxlength="50" size="46" placeholder="info@example.com" ></td>
<td>ここにエラー時の表示をさせたい</td>
</tr>
ということで、変数に代入しました。
$error = ($_POST['email1'] ."は既に登録されています");
<tr>
<td>E-mail</td>
<td colspan="2"><input type="email" name="email1" maxlength="50" size="46" placeholder="info@example.com" ></td>
<td><?php $error ?></td>
</tr>
スコープの関係で呼び出せてないだろうなとは思いますが、
まだ勉強中の身で、この例だと$errorはif内でしか呼び出せなかったことを学んだ記憶があります。
アドレスの重複チェックを定義したものを呼び出すには、どうしたら良いのでしょうか?
最終的にはクラスを作って呼び出したいのです...
<?php
class mail{
function collation(){
$dsn = 'mysql:dbname=test;host=localhost;charset=utf8';
$user = 'root';
$password = '';
try{
$dbh = new PDO($dsn, $user, $password);
$dbh->query('SET NAMES sjis');
$sql = 'select * from userdata';
foreach ($dbh->query($sql) as $row) {
if($row['email'] == $_POST['email1']){
$error = ($_POST['email1'] . "は既に登録されています");
}
}
}catch (PDOException $e){
print('Error:'.$e->getMessage());
die();
}
$dbh = null;
}
}
?>
<tr>
<td>E-mail</td>
<td colspan="2"><input type="email" name="email1" maxlength="50" size="46" placeholder="info@example.com" ></td>
<td><?php mail::collation(); ?></td>
</tr>
イメージは大体あってると思うのですが、記述をどこか間違えていることは自覚していますが、どうすればよいのかわからず...
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
<?php
//$dsn = 'mysql:dbname=test;host=localhost;charset=utf8';
$dsn = 'mysql:dbname=test;host=localhost;charset=sjis';
$user = 'root';
$password = '';
$email = filter_input(INPUT_POST, 'email');
try {
// try ~ catch で例外を受けるためには必要
$option = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
// $dbh = new PDO($dsn, $user, $password);
$dbh = new PDO($dsn, $user, $password, $option);
// $dbh->query('SET NAMES sjis'); // <- ダメ $dsn で設定する
// $sql = 'select * from userdata';
$sql = 'select count(*) as cnt from userdata where email=?';
$stmt = $dbh->prepare($sql);
$arrParam = array();
$arrParam[] = $email;
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (0 < $row['cnt']) {
$error = "{$email}は既に登録されています";
}
// 全件取得して、PHPでループなんて無駄以外の何物でもない
// foreach ($dbh->query($sql) as $row) {
// if ($row['email'] == $_POST['email1']) {
// echo ($_POST['email1'] . "は既に登録されています");
// }
// }
} catch (PDOException $e) {
$error = $e->getMessage();
}
// $dbh = null; // <- 不要 どうしても必要なら、末尾で。
?>
<tr>
<td>E-mail</td>
<td colspan="2"><input type="email" name="email1" maxlength="50" size="46" placeholder="info@example.com" ></td>
<td>
<?php
if (isset($error)) {
echo $error;
}
?>
</td>
</tr>
<?php
$dbh = null; // <- どうしても必要なら、ここ。
?>
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
echo
とりあえず、変数がどこで変化しているか、var_dump
等で、チェックするクセをつけるとイイですよ。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.35%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2016/06/05 15:03
ただ、エラーがでてしまいます...
SQLSTATE[HY093]: Invalid parameter number: no parameters were bound
$email = filter_input(INPUT_POST, 'email');
と
$error = "{$email}は既に登録されています";
は
$email = filter_input(INPUT_POST, 'email1');
と
$error = "{$email1}は既に登録されています";
でなくてよいのでしょうか?
2016/06/05 15:13
2016/06/05 15:37
2016/06/05 16:06
そのせいで、プリペアドステートメントのプレースホルダ(?の箇所)に値が割り当てられていないのが原因かと思われます。
$arrParam = array();
$arrParam[] = $email;
$stmt->execute();
このコードを、以下のように修正してください。
$arrParam = array();
$arrParam[] = $email;
$stmt->execute($arrParam);
または、以下のように見やすくしても良いかもしれません。
$stmt->execute(array($email));
2016/06/05 16:12
2016/06/05 17:15
提示していただいたコードで正常に動作しました!
合間にphpリファレンス見ながら自分でも改良してみました...
お時間がありましたらアドバイス頂けると嬉しいです。
$dsn = 'mysql:dbname=test;host=localhost;charset=utf8';
$user = 'root';
$password = '';
$email1 = filter_input(INPUT_POST, 'email1');
try{
$dbh = new PDO($dsn, $user, $password);
$dbh -> setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh -> setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
$sql = 'SELECT count(*) AS cnt FROM userdata WHERE email=?';
$prepare =$dbh->prepare($sql);
//プレースホルダーに$mail1をバインド
$prepare->bindValue(1,$email1,PDO::PARAM_STR);
$prepare->execute();
$result = $prepare->fetchColumn();
if($result > 0){
echo "{$email1}は既に登録されています。";
}
}catch (PDOException $e) {
echo "Error:".$e->getMessage();
}
2016/06/05 17:43 編集
2016/06/05 18:08
あと...
クラス化しなければ
if (isset($error)) { echo $error; }
で呼び出せるのですが
クラス化してしまうと
if (isset($error)) { echo $error; }
で呼び出してDBに登録しているアドレスを入力してみても
表示されないんです...
2016/06/05 18:18
2016/06/05 18:18 編集
2016/06/05 18:21
2016/06/05 18:24
クラス化はまた別で質問してみようと思います。
一応、最終的にはこういう使い方をしようとしていたんです。
class mail{
function collation(){
$dsn = 'mysql:dbname=test;host=localhost;charset=utf8';
$user = 'root';
$password = '';
$email = filter_input(INPUT_POST, 'email1');
try{
$option = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
$dbh = new PDO($dsn, $user, $password, $option);
$sql = 'select count(*) as cnt from userdata where email=?';
$stmt = $dbh->prepare($sql);
$arrParam = array();
$arrParam[] = $email;
$stmt->execute($arrParam);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (0 < $row['cnt']) {
$error = "{$email}は既に登録されています";
return $error;
}
} catch (PDOException $e) {
$error = $e->getMessage();
return $error ;
}
}
}
<td><?php echo mail::collation(); ?></td>
これで<td>に表示ができます。
何度もお付き合い頂いて本当にありがとうございます。
2016/06/05 18:27
2016/06/05 19:39
質問を放置しすぎ。解決しているものは閉じてください。