2011-08-31 140 views
1

操作:创建表记录,该记录是唯一键上的副本。PHP MySQL在唯一索引上创建重复记录奇怪失败

好:独特的键正在工作,因为没有创建重复记录。

不好:我在PHP中使用的mysqli函数没有按我期望的方式失败。

Meta:我有一些PHP(运行5.3.6),它处理从AJAX POST请求在Mysql(5.5.9)表中创建新记录。身份验证和输入清理和验证在我分享的代码范围之外处理。响应函数还处理以有效格式输出响应。我插入的表格有一个自动递增的id列和一个唯一的名称列。

// connect to server 
$mysqli = new mysqli("localhost", "dbuser", 'dbpassword', "database"); 
if(mysqli_connect_errno()) { 
    $response["message"] = "unable to connect to the MySQL server at 'localhost' as 'dbuser' using a password or select the database 'database' because ".mysqli_connect_errno(); 
    respond($response); 
} 

// build and run query 
if ($stmt = $mysqli -> prepare("INSERT INTO `database`.`table` (`id`, `name`) VALUES (NULL, ?);")) { 
    $stmt -> bind_param("s", $inputs["name"]); 
    $success = $stmt -> execute(); 
    if ($success) { 
     $response["status"] = "success"; 
     $response["id"] = $mysqli -> insert_id; 
     respond($response); 
    } else { 
     $response["message"] = "failed to insert because ".$stmt -> error; 
    } 

    $stmt -> close(); 
} else { 
    $response["message"] = "unable to build query because ".$mysqli -> error; 
    respond($response); 
} 

$mysqli -> close(); 

可正常工作插入一个新的独特的名称时,但试图插入新的重复名称时不返回任何东西。我预计

$stmt -> execute(); 

失败,所以我会返回一个解释错误的回应。这段代码没有这样做。我发现的唯一方法,返回创建失败,因为重复是这样的紧密语句前加上两行代码:

// connect to server 
$mysqli = new mysqli("localhost", "dbuser", 'dbpassword', "database"); 
if(mysqli_connect_errno()) { 
    $response["message"] = "unable to connect to the MySQL server at 'localhost' as 'dbuser' using a password or select the database 'database' because ".mysqli_connect_errno(); 
    respond($response); 
} 

// build and run query 
if ($stmt = $mysqli -> prepare("INSERT INTO `database`.`table` (`id`, `name`) VALUES (NULL, ?);")) { 
    $stmt -> bind_param("s", $inputs["name"]); 
    $success = $stmt -> execute(); 
    if ($success) { 
     $response["status"] = "success"; 
     $response["id"] = $mysqli -> insert_id; 
     respond($response); 
    } else { 
     $response["message"] = "failed to insert because ".$stmt -> error; 
    } 

    $stmt -> close(); 
} else { 
    $response["message"] = "unable to build query because ".$mysqli -> error; 
    respond($response); 
} 

$response["message"] = "Duplicate"; 
respond($response); 

$mysqli -> close(); 

我不明白的事情是当查询运行作为预计,重复的响应不会返回。当查询因尝试在唯一键上插入副本而失败时,将返回重复的响应。

问题:为什么一个成功的插入不能在代码块的末尾运行响应函数?

问题:为什么插入失败是因为尝试在唯一键上插入重复项而不会引发异常或按我的预期失败?

我也尝试在try catch块中包装整个东西,但它没有任何帮助,因为它没有抛出任何异常。如果你能解决这个问题,我将不胜感激。

回答

3

问题:为什么成功的插入不能在代码块的末尾运行响应函数?

我假设你respond方法中有一个exitdie的地方,暂停执行。

问题:为什么插入失败的插入是因为尝试在唯一键上插入副本而不会引发异常或失败,如我所料?

我认为这与您的if声明中的逻辑有关。

如果你的程序不断进入无响应不断发送else语句

$response["message"] = "failed to insert because ".$stmt -> error; 

(该respond函数永远不会被调用)。你的第二个例子工作的原因是因为代码每次都达到这个点(因为它在最后的else声明之外)。如果你在上面的行之后将呼叫移动到respond,你可能会发现它会按预期返回消息。以下内容:

// connect to server 
$mysqli = new mysqli("localhost", "dbuser", 'dbpassword', "database"); 
if(mysqli_connect_errno()) { 
    $response["message"] = "unable to connect to the MySQL server at 'localhost' as 'dbuser' using a password or select the database 'database' because ".mysqli_connect_errno(); 
    respond($response); 
} 

// build and run query 
if ($stmt = $mysqli -> prepare("INSERT INTO `database`.`table` (`id`, `name`) VALUES (NULL, ?);")) { 
    $stmt -> bind_param("s", $inputs["name"]); 
    $success = $stmt -> execute(); 
    if ($success) { 
     $response["status"] = "success"; 
     $response["id"] = $mysqli -> insert_id; 
     respond($response); 
    } else { 
     $response["message"] = "failed to insert because ".$stmt -> error; 
     respond($response); // <-- this is the bit you need 
    } 

    $stmt -> close(); 
} else { 
    $response["message"] = "unable to build query because ".$mysqli -> error; 
    respond($response); 
} 

$mysqli -> close(); 
+0

得到错误信息,在这里,我在想,我快要疯了果然我错过了调用回复功能感谢您的帮助。有时候最好只是走开,稍后再看看,谢谢你帮助我。 –

+1

没问题,恰巧t o我们最好的:) – phindmarsh

1

尝试从$stmt->errorCode()$stmt->errorInfo()