2

登録時にユーザー名やメールアドレスが重複していないか、MySQLテーブルをチェックインする方法を考えていました。これが私がこれまでに試したことですが、役に立ちませんでした:

$username = $_POST['username'];
$sq = $db->exec("SELECT * FROM `users` WHERE `username` = '$username'");
if ($sq->rowCount() > 0)
{
    $msg = "That username is already taken.";
    $error = true;
}

$email = $_POST['email'];
$sq = $db->exec("SELECT * FROM `users` WHERE `email` = '$email'");
if ($sq->rowCount > 0)
{
    $msg = "That email is already taken.";
    $error = true;
}

if (!error)
{
    //add to db
}

これが与えるエラーはCall to a member function rowCount() on a non-object

手伝ってもらえますか?

4

3 に答える 3

5

PDO::exec()整数を返すため、上記のコードは。の行に沿って致命的なエラーで終了しcall to member function rowCount() on a non-objectます。このために行うべきことはSELECT COUNT(*)、行数を取得することです。

例外を使用して、エラー処理プロセスを支援することもできます。

このような:

// Ensure PDO will throw exceptions on error
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// Turn emulated prepares off
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);

try {

  // Check if username is taken
  $stmt = $db->prepare("SELECT COUNT(*) FROM `users` WHERE `username` = :username");
  $stmt->execute(array('username' => $_POST['username']));
  if ($stmt->fetchColumn() > 0) {
    throw new Exception("That username is already taken.");
  }

  // Check if email is taken
  $stmt = $db->prepare("SELECT COUNT(*) FROM `users` WHERE `email` = :email");
  $stmt->execute(array('email' => $_POST['email']));
  if ($stmt->fetchColumn() > 0) {
    throw new Exception("That email is already taken.");
  }

  // Username and email are free

} catch (PDOException $e) {

  // A database error occured

} catch (Exception $e) {

  // Either the username of email is taken

}

列のデータが一意である必要がある場合は、重複する挿入を防ぎ、その列の値に基づいて検索するクエリを高速化するために、そのデータに一意のインデックスを付ける必要があります。

于 2012-09-15T00:23:49.063 に答える
2

潜在的な競合状態を回避するには、ユーザー名と電子メールのフィールドを一意のインデックスとして設定するだけです。

重複する行を挿入しようとすると、データベースエンジンから特定のエラーコードが表示されます。MySQLの場合は1062です。

クエリが失敗した場合は、エラー番号が重複行のエラー番号であるかどうかを確認し、それに基づいてメッセージを表示します。

少なくとも、データベースレベルでの重複を防ぐために、列は一意のインデックスである必要があります。

于 2012-09-15T00:35:30.527 に答える
0

$ dbのタイプをsqllite3と想定して、明確にしてください。

http://php.net/manual/en/sqlite3.exec.phpでSQLLITE3::exec()のドキュメントを確認してください..それが言う限り、それは(UPDATE、INSERT、DELETE)に対してのみ有効であり、ブール値を返します。したがって、コードはおそらく実行されません。

タグによると、MySQLを使用しています。mysql / mysqli拡張機能、mysql_query()&mysqli_query()、または$ dbがmysqliタイプの場合は、$ db-> query()を確認する必要があると思います。

于 2012-09-15T00:23:38.443 に答える