Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/240.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在mysql表中插入唯一的电子邮件_Php_Mysql_Mysqli_Sql Insert - Fatal编程技术网

Php 如何在mysql表中插入唯一的电子邮件

Php 如何在mysql表中插入唯一的电子邮件,php,mysql,mysqli,sql-insert,Php,Mysql,Mysqli,Sql Insert,我想从用户那里获取电子邮件地址,将其添加到邮件列表中。但是,我希望防止重复条目,因此我使用插入忽略方法。我正在使用下面的PHP脚本,但不断收到此错误: 致命错误:未捕获错误:调用bool上的成员函数bind_param() 我已经阅读了很多关于这个错误的SO文章,但仍然无法让它起作用。我已经确认$email和$id变量确实有值。我怀疑这个错误一定与使用IGNORE有关,但我真的不知道 这是我的密码: $email = filter_input(INPUT_POST, 'email',FI

我想从用户那里获取电子邮件地址,将其添加到邮件列表中。但是,我希望防止重复条目,因此我使用插入忽略方法。我正在使用下面的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);
我尝试只为insert包含一个变量,但在两个bind_param行中都出现了错误。当我将这两个变量都包含在一个bind_param条目中时,我也遇到了错误


我对避免数据库中重复电子邮件的其他方法持开放态度,只要它们可以用一个PHP文件完成。

我只是猜测,但是,您的值是否错误? 试试这个:

 $sqlQuery = 'INSERT IGRNORE INTO email(email, id) VALUES($email,$id);';

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

PDO 打开连接,在不忽略的情况下执行语句,然后捕获异常以查看其失败原因。代码
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中,您不能使用命名占位符,也不能在execute中绑定。
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;
    }
}

如果直接在mysql服务器上运行sql命令(使用值而不是占位符),会发生什么情况?这是PDO和mysqli的混合。mysqli没有命名占位符,也没有单个绑定。IGRNORE不是一个单词。可能最好忽略。@RobBiermann在服务器上运行该命令仍然会产生相同的错误,即使在从“忽略”(@草莓)一词中删除多余的R之后也是如此。最后,我成功地找到了这个问题的公认答案:这段代码不正确,因为您正在将php变量注入字符串中,但不使用双引号,因此,
$email
$id
将被解释为文字警告:您对参数化准备语句非常开放,应该使用参数化准备语句,而不是手动构建查询。它们由或提供。永远不要相信任何形式的输入!即使您的查询仅由受信任的用户执行。你是对的,我混合了SQLI和PDO,但不知怎么的,在本期之前它一直在跨多个文件工作。我现在不得不通过我所有的代码来确定只有一种格式(PDO),但这是最好的。谢谢你的帮助!虽然此解决方案在我的开发环境中工作,但在生产环境中却不起作用。我最终在这个问题上使用了公认的解决方案:@jeffbartelli它不起作用意味着什么?你有错误吗?我没有找到具体的错误。当我对脚本进行基本测试时,它无法将记录保存到生产环境中的数据库中,但无法保存到虚拟开发环境中。我尝试隔离脚本并运行它,但它只返回脚本已成功运行。当然,我是PHP新手,所以有更好的方法返回错误消息。。。