我可以使用PHP检测并处理MySQL警告吗?
我正在处理将JobName列定义为UNIQUE的MySQL表。如果有人试图使用已存在于数据库中的JobName将新Job保存到数据库,则MySQL将引发警告。我可以使用PHP检测并处理MySQL警告吗?
我想能够检测这个警告,就像一个错误,在我的PHP脚本,并用它妥善处理。理想情况下,我想知道MySQL抛出了什么样的警告,以便我可以分支代码来处理它。
这可能吗?如果没有,是因为MySQL没有这个能力,PHP没有这个能力,或者两者兼而有之?
的警告是“标记”,以PHP本身就需要改变在MySQL/MySQLi驱动程序,这显然超出了这个问题的范围。相反,你将不得不基本检查您使数据库的警告在每次查询:
$warningCountResult = mysql_query("SELECT @@warning_count");
if ($warningCountResult) {
$warningCount = mysql_fetch_row($warningCountResult);
if ($warningCount[0] > 0) {
//Have warnings
$warningDetailResult = mysql_query("SHOW WARNINGS");
if ($warningDetailResult) {
while ($warning = mysql_fetch_assoc(warningDetailResult) {
//Process it
}
}
}//Else no warnings
}
显然,这将是可怕昂贵适用EN-质量,所以你可能需要仔细想想,当以及如何产生警告(这可能导致您重构以消除它们)。
仅供参考,MySQL SHOW WARNINGS
当然,你可以用的SELECT @@warning_count
,这将节省您每次执行一个查询的初始查询免除,但我把它的迂腐完整性。
首先,您应该turn warnings off以便您的访客不会看到您的MySQL错误。其次,当你打电话给mysql_query()
时,你应该检查它是否返回错误。如果确实如此,请拨打mysql_errno()
以查明问题所在。将返回的编号与this page上的错误代码相匹配。
它看起来这是你要找的错误编号:
Error: 1169 SQLSTATE: 23000 (ER_DUP_UNIQUE)
Message: Can't write, because of unique constraint, to table '%s'
如果我没有记错他询问的警告,而不是错误。警告仍然允许查询通过,因此`mysql_query`不会返回`false`。请参阅iAn对PHP有限警告支持的回答。 – Andrew 2013-12-07 20:36:09
更新,删除有关错误号的功能,我现在认识到没有在您的情况适用的东西...
一件事在MySQL警惕的为UPDATE
声明:mysqli_affected_rows()
将返回零,即使WHERE
子句匹配的行,但SET
条款实际上并没有改变数据值。我只提到这一点,因为这种行为导致了我曾经看到的一个系统中的错误 - 程序员使用该返回值在更新后检查错误,假设零表示发生了一些错误。这只是表示用户在单击更新按钮之前没有更改任何现有值。
所以我想用mysqli_affected_rows()
也不能依靠找到这样的警告,除非你有像表中的update_time
列这样的东西,总是会被分配一个新的时间戳值更新时。这种解决方法似乎有点kludgey虽然。
取决于什么(如果有的话),你正在使用的框架,我建议你做一个查询,以检查作业名自己,并与验证的表格的其余部分创建正确的信息给用户。
根据jobnames的数量,你可以在名称发送到包含形式和使用JavaScript来告诉使用其所持的看法。
如果这对你没有意义,那么总结我的观点是这样的:不要设计你的程序和/或用户试图做非法的事情,并在他们做和处理它时捕捉错误。设计你的系统不会造成错误会更好,恕我直言。保持错误实际的错误:)
您可以检测使用的mysqli语句错误没有唯一键冲突。 mysqli语句返回错误1062,即ER_DUP_ENTRY。您可以查找错误1062并打印适当的错误消息。如果你想打印你的列(jobName)也作为你的错误信息的一部分,那么你应该解析语句错误字符串。
if($stmt = $mysqli->prepare($sql)){ $stmt->bind_param("sss", $name, $identKey, $domain); $stmt->execute(); if($mysqli->affected_rows != 1) { //This will return errorno 1062 trigger_error('mysql error >> '.$stmt->errno .'::' .$stmt->error, E_USER_ERROR); exit(1); } $stmt->close(); } else { trigger_error('mysql error >> '. $mysqli->errno.'::'.$mysqli->error,E_USER_ERROR); }
有可能得到警告,并且以比mysql更高效的方式使用mysqli。
这里使用的是人工page建议在php.net的财产mysqli-> WARNING_COUNT代码:上抑制警告
$mysqli->query($query);
if ($mysqli->warning_count) {
if ($result = $mysqli->query("SHOW WARNINGS")) {
$row = $result->fetch_row();
printf("%s (%d): %s\n", $row[0], $row[1], $row[2]);
$result->close();
}
}
注:一般来说,它是不以防止警告是个好主意显示,因为你可能会错过重要的东西。如果你绝对必须隐藏某种原因警告,可以放置一个@
标志在声明前做一个单独的基础上。这样,您不必关闭所有警告报告,并可以将其限制为特定实例。
例子:
// this suppresses warnings that might result if there is no field titled "field" in the result
$field_value = @mysql_result($result, 0, "field");
这听起来像用户希望能够捕获错误,不surpress它。 – pgreen2 2012-11-29 04:42:21
ini_set('mysql.trace_mode', 1)
可能是你在找什么。
的PHP错误然后可以用自定义的PHP错误处理程序处理,但你也可以只是关闭显示PHP错误,因为它们通常被记录到日志文件(取决于你的PHP配置)。
或者使用具有warning_count属性的MySQLi驱动程序。 http://php.net/manual/en/mysqli.warning-count.php – 2011-10-19 12:33:59