【问题标题】:How to insert unique email into mysql table [duplicate]如何将唯一的电子邮件插入mysql表[重复]
【发布时间】:2020-11-11 21:55:00
【问题描述】:

我想从用户那里获取电子邮件地址,以将他们添加到邮件列表中。但是,我想防止重复条目,所以我使用 INSERT IGNORE 方法。我正在使用下面的 PHP 脚本,但经常收到此错误:

致命错误:未捕获的错误:在 bool 上调用成员函数 bind_param()

我已经查看了很多关于此错误的 SO 文章,但仍然无法使其正常工作。我已经确认 $email 和 $id 变量确实有值。我怀疑这个错误一定与 IGNORE 的使用有关,但老实说我不知道​​。

这是我的代码:

    $email = filter_input(INPUT_POST, 'email',FILTER_SANITIZE_EMAIL);
    $id = filter_input(INPUT_POST, 'id',FILTER_VALIDATE_INT) ?: NULL;
    
    $sqlQuery = 'INSERT IGRNORE INTO email(email, id) VALUES(:email,:id);';
    $stmt = $dbc->prepare($sqlQuery);
    $stmt->bind_param(':email',$email);
    $stmt->bind_param(':id',$id);
    $stmt->execute();
    mysqli_close($dbc);

我尝试只包含一个用于插入的变量,但我得到了针对两个 bind_param 行的错误。当我将这个结构设置为在单个 bind_param 条目中包含两个变量时,我也遇到了错误。

我愿意接受其他避免数据库中重复电子邮件的方法,只要它们可以使用单个 PHP 文件来完成。

【问题讨论】:

  • 如果直接在mysql服务器上运行sql命令会发生什么(用值代替占位符)?
  • 您正在混合使用 PDO 和 mysqli。 mysqli 没有命名占位符,也没有单一绑定。
  • IGRNORE 不是一个词。可能最好忽略。
  • @RobBiermann 在服务器上运行命令仍然产生相同的错误,即使从单词 IGNORE (@Strawberry) 中删除了多余的 R。最后,我通过接受这个问题的答案找到了成功:stackoverflow.com/questions/25996040/…

标签: php mysql mysqli sql-insert


【解决方案1】:

您正在混合使用 PDO 和 mysqli 语法。你需要选择一个。

PDO

打开连接,执行不带IGNORE的语句,然后捕获异常,看看为什么会失败。代码1062表示MySQL试图插入重复值。

$pdo = new PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", 'user', 'pass', [
    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
    \PDO::ATTR_EMULATE_PREPARES => false
]);

try {
    $stmt = $pdo->prepare('INSERT INTO email(email, id) VALUES(:email,:id)');
    $stmt->execute([
        'email' => $email,
        'id' => $id
    ]);
} catch (PDOException $e) {
    if ($e->errorInfo[1] === 1062) {
        // duplicate
    } else {
        // If not 1062 then rethrow
        throw $e;
    }
}

mysqli

使用 mysqli 会做更多的工作,但逻辑相同。使用 mysqli,您不能使用命名占位符,也不能在执行中绑定。 bind_param() 函数非常奇特,所以要特别注意语法。

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'user', 'pass', 'test');
$mysqli->set_charset('utf8mb4'); // always set the charset

try {
    $stmt = $mysqli->prepare('INSERT INTO email(email, id) VALUES(?, ?)');
    $stmt->bind_param('ss', $email, $id);
    $stmt->execute();
} catch (mysqli_sql_exception $e) {
    if ($e->getCode() === 1062) {
        // duplicate
    } else {
        // If not 1062 then rethrow
        throw $e;
    }
}

【讨论】:

  • 你是对的,我正在混合 SQLI 和 PDO,但不知何故,它一直在处理多个文件,直到这个问题。我现在必须检查我的所有代码才能只选择一种格式(PDO),但这是最好的。感谢您的帮助!
  • 虽然此解决方案在我的开发环境中有效,但在生产环境中无效。我最终在这个问题中使用了公认的解决方案:link
  • @jeffbartelli 它不起作用是什么意思?你收到错误了吗?
  • 我没有找到具体的错误。当我对脚本进行基本测试时,它未能将记录保存到生产中的数据库中,但在我的虚拟开发环境中却没有。我尝试隔离脚本并运行它,但它只返回脚本已成功运行。当然,我是 PHP 新手,所以很可能有更好的方法来返回错误消息...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-11
  • 1970-01-01
  • 2011-07-15
  • 1970-01-01
  • 1970-01-01
  • 2021-04-21
相关资源
最近更新 更多