我正试图绕过MySQli,我对错误报告感到困惑。 我使用MySQLi'prepare'语句的返回值来检测执行SQL时的错误,如下所示:
$stmt_test = $mysqliDatabaseConnection->stmt_init();
if($stmt_test->prepare("INSERT INTO testtable VALUES (23,44,56)"))
{
$stmt_test->execute();
$stmt_test->close();
}
else echo("Statement failed: ". $stmt_test->error . "<br>");
但是,prepare语句的返回值是仅检测SQL语句的预处理中是否存在错误而未检测到执行错误?如果是这样,我应该更改我的执行行以标记错误,如下所示:
if($stmt_test->execute()) $errorflag=true;
然后为了安全,我应该在声明执行后执行以下操作:
if($stmt_test->errno) {$errorflag=true;}
...或者我可以开始使用MySQLi prepare'语句的返回值捕获与它定义的查询的完整执行相关的所有错误吗?
由于 ç
答案 0 :(得分:113)
我在过去两天之前曾两次写过这篇文章(所以对我而言,即使问题开始有点不同,也是重复的。)
mysqli的每种方法都可能失败。您应该测试每个返回值。如果一个失败,请考虑继续使用不符合您期望状态的对象是否有意义。 (可能不是处于“安全”状态,但我认为这不是问题。)
由于每个连接/语句只存储了最后一个操作的错误消息,因此如果在出现错误后继续,则可能会丢失有关 导致错误的信息。您可能希望使用该信息让脚本决定是再次尝试(仅限临时问题),更改内容还是完全拯救(并报告错误)。它使调试变得更加容易。
$stmt = $mysqli->prepare("INSERT INTO testtable VALUES (?,?,?)");
// prepare() can fail because of syntax errors, missing privileges, ....
if ( false===$stmt ) {
// and since all the following operations need a valid/ready statement object
// it doesn't make sense to go on
// you might want to use a more sophisticated mechanism than die()
// but's it's only an example
die('prepare() failed: ' . htmlspecialchars($mysqli->error));
}
$rc = $stmt->bind_param('iii', $x, $y, $z);
// bind_param() can fail because the number of parameter doesn't match the placeholders in the statement
// or there's a type conflict(?), or ....
if ( false===$rc ) {
// again execute() is useless if you can't bind the parameters. Bail out somehow.
die('bind_param() failed: ' . htmlspecialchars($stmt->error));
}
$rc = $stmt->execute();
// execute() can fail for various reasons. And may it be as stupid as someone tripping over the network cable
// 2006 "server gone away" is always an option
if ( false===$rc ) {
die('execute() failed: ' . htmlspecialchars($stmt->error));
}
$stmt->close();
编辑:六年后的几个笔记....
mysqli扩展完全能够报告通过异常导致(mysqli)错误代码不是0的操作,请参阅mysqli_driver::$report_mode。
die()真的非常粗糙,即使是像这样的例子也不会用它。
所以,请忽略每个(mysql)操作 失败的事实,原因很多;即使如果之前完全相同的事情已经进行了一千次......
答案 1 :(得分:15)
<强>完整性强>
您需要同时检查$mysqli
和$statement
。如果它们是错误的,则需要分别输出$mysqli->error
或$statement->error
。
<强>效率强>
对于可能终止的简单脚本,我使用简单的单行程序来触发PHP错误。对于更复杂的应用程序,应该激活错误警告系统,例如通过抛出异常。
用法示例1:简单脚本
# This is in a simple command line script
$mysqli = new mysqli('localhost', 'buzUser', 'buzPassword');
$q = "UPDATE foo SET bar=1";
($statement = $mysqli->prepare($q)) or trigger_error($mysqli->error, E_USER_ERROR);
$statement->execute() or trigger_error($statement->error, E_USER_ERROR);
用法示例2:应用
# This is part of an application
class FuzDatabaseException extends Exception {
}
class Foo {
public $mysqli;
public function __construct(mysqli $mysqli) {
$this->mysqli = $mysqli;
}
public function updateBar() {
$q = "UPDATE foo SET bar=1";
$statement = $this->mysqli->prepare($q);
if (!$statement) {
throw new FuzDatabaseException($mysqli->error);
}
if (!$statement->execute()) {
throw new FuzDatabaseException($statement->error);
}
}
}
$foo = new Foo(new mysqli('localhost','buzUser','buzPassword'));
try {
$foo->updateBar();
} catch (FuzDatabaseException $e)
$msg = $e->getMessage();
// Now send warning emails, write log
}
答案 2 :(得分:4)
不确定这是否能回答您的问题。对不起,如果不是
要从mysql数据库报告有关查询的错误,您需要使用连接对象作为焦点。
这样:
echo $mysqliDatabaseConnection->error
将回应mysql发送的有关您查询的错误。
希望有所帮助