在 MySQLi 中将查询错误转换为异常 [duplicate]

Turning query errors to Exceptions in MySQLi [duplicate]

提问人:Roman Newaza 提问时间:1/29/2013 最后编辑:Roman Newaza 更新时间:1/15/2020 访问量:29159

问:

我正在尝试将 MySQLi 查询错误转换为异常,但不能 - 只有当它无法连接数据库时才会抛出mysqli_sql_exception

我使用了嵌入到自定义包装类的过程 MySQLi 函数。mysqli_report(MYSQLI_REPORT_STRICT)

原代码:

public function mysqlQuery($SQL) {

    $this->Result = mysqli_query($this->DBlink, $SQL);

    if($this->Result === false)
        throw new MySQLiQueryException($SQL, mysqli_error($this->DBlink), mysqli_errno($this->DBlink));

    return $this->Result;

}

问题:查询失败时没有警告或异常是正常的,所以我必须检查 mysqli_query() 是否返回 false?

PHP MySQLI

评论

1赞 Vlad Preda 1/29/2013
据我所知,mysqli 仅在 DB connect 上抛出异常。所以。。。差不多,是的。你有mysqli_errno、mysqli_error和其他功能,所以你知道错误,但这是限制。
0赞 k102 1/29/2013
如果某些人出错,您可以抛出异常try, catch, throw
0赞 Roman Newaza 1/29/2013
@k102,我试图将该部分从我的代码中放入MySQLi。
0赞 Roman Newaza 1/29/2013
@VladPreda我明白了,接缝就像我必须保持现在的样子。

答:

45赞 Your Common Sense 1/29/2013 #1

前段时间,我设法解决了这个问题。正如另一个答复所指出的,

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

是告诉 mysqli 抛出异常的正确方法。

只要确保不要将每个查询都包装在 try-catch 中即可。这是一个非常普遍的误解,即一旦你开始使用异常,你就应该开始向左和向右投掷尝试和接球。恰恰相反,try-catch 应该谨慎使用。虽然 99% 的错误不应该就地处理,而应该由站点范围的错误处理程序处理。你可以从我关于PHP错误报告的文章中阅读更多关于这个主题的信息

评论

3赞 Roman Newaza 1/29/2013
这就是现在的样子。我在问是否可以指示 MySQLi 驱动程序抛出异常,就像您对 PDO 所做的那样。
2赞 Karoly Horvath 1/29/2013
是的,你的问题很清楚。但是使用包装函数来执行查询(一个非常)好的做法,一旦你有了它,添加额外的两行就很容易了。
0赞 Simone Rossaini 5/20/2021
PHP错误的链接是这样的
28赞 MrWhite 1/10/2014 #2

我必须检查 mysqli_query() 是否返回 false?

不。

您应该能够执行所需的操作,并指示 mysqli 驱动程序在 SQL 错误上抛出异常,但如果尚未启用,则需要启用。MYSQLI_REPORT_ERROR

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT)

mysqli_query()现在应该在出错时引发异常。您不需要检查失败的返回值(无论如何都不会发生,因为会引发异常)。

public function mysqlQuery($SQL) {
    try {
        $this->Result = mysqli_query($this->DBlink, $SQL);
    } catch (mysqli_sql_exception $e) {
        throw new MySQLiQueryException($SQL, $e->getMessage(), $e->getCode());
    }
    return $this->Result;
}

(注意:我在重新抛出的异常中更改为。$this->SQL$SQL

评论

0赞 Louis Loudog Trottier 5/12/2017
您正在使用 mysqli_sql_exception' 是否允许使用方法 $e->getCode()',并且这将反映我猜的 $mysqli->errno?
1赞 MrWhite 5/12/2017
@LouisLoudogTrottier Yes, 是对象的方法,因此仅在该异常类型的 catch 块的作用域中可用。getCode()mysqli_sql_exception
3赞 st__gen_server 3/10/2015 #3

我知道这有点太晚了,但为了子孙后代。我发现MYSQLI_REPORT_STRICT限制性的,某些例外情况没有被提出,因此它们不能被捕获块处理。

 mysqli_report(MYSQLI_REPORT_ALL); // Traps all mysqli error 

 try {
    $mysqli = new mysqli('localhost','user,'pwd','db');

     /* I don't need to explicitly throw an exception as this is being
      done automatically */

 } catch(Exception $e) {
    echo $e->getMessage();
 }  

评论

0赞 Louis Loudog Trottier 5/12/2017
Exception $e会自行捕获 mysqli 故障还是我们需要使用?还是等价的?还是因为 mysqli_report(MYSQLI_REPORT_ALL);' 而使用了 Exception?mysqli_sql_exception $e
1赞 MrWhite 5/12/2017
@LouisLogTrottier对象是所有异常的父类(是一个子类),因此它自然会捕获所有内容Exceptionmysqli_sql_exception
2赞 Your Common Sense 5/5/2020
catch(Exception $e) { echo $e->getMessage();是一个无用的货物崇拜代码。如果你把它拿出来,结果是一样的:PHP已经报告了未捕获的异常。