PHP try/catch 和致命错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12928487/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 04:29:40  来源:igfitidea点击:

PHP try/catch and fatal error

phptry-catchfatal-error

提问by Ploppe

I'm using the following script to use a database using PHP:

我正在使用以下脚本使用 PHP 使用数据库:

try{
    $db = new PDO('mysql:host='.$host.';port='.$port.';dbname='.$db, $user, $pass, $options);
}
catch(Exception $e){
    $GLOBALS['errors'][] = $e;
}

Now, I want to use this database handle to do a request using this code:

现在,我想使用此数据库句柄使用以下代码执行请求:

try{
    $query = $db->prepare("INSERT INTO users (...) VALUES (...);");
    $query->execute(array(
        '...' => $...,
        '...' => $...
    ));
}
catch(Exception $e){
    $GLOBALS['errors'][] = $e;
}

Here is the problem:

这是问题所在:

  • When the connection to the DB is OK, everything works,
  • When the connection fails but I don't use the DB, I have the $GLOBALS['errors'][]array and the script is still running afterwards,
  • When the connection to the DB has failed, I get the following fatal error:
  • 当与数据库的连接正常时,一切正常,
  • 当连接失败但我不使用数据库时,我有$GLOBALS['errors'][]数组,之后脚本仍在运行,
  • 当与数据库的连接失败时,我收到以下致命错误:

Notice: Undefined variable: db in C:\xampp\htdocs[...]\test.php on line 32

Fatal error: Call to a member function prepare() on a non-object in C:\xampp\htdocs[...]\test.php on line 32

注意:未定义变量:db in C:\xampp\htdocs[...]\test.php on line 32

致命错误:在第 32 行调用 C:\xampp\htdocs[...]\test.php 中的非对象上的成员函数 prepare()

Note:Line 32 is the $query = $db->prepare(...)instruction.

注意:第 32 行是$query = $db->prepare(...)指令。

That is to say, the script crashes, and the try/catch seems to be useless. Do you know why this second try/catch don't works and how to solve it?

也就是说,脚本崩溃了,try/catch 好像也没用了。您知道为什么第二次尝试/捕获不起作用以及如何解决吗?

Thanks for the help!

谢谢您的帮助!

EDIT:There are some really good replies. I've validated one which is not exactly what I wanted to do, but which is probably the best approach.

编辑:有一些非常好的答复。我已经验证了一个并不是我想要做的,但这可能是最好的方法。

回答by Explosion Pills

try/catchblocks only work for thrown exceptions (throw Exceptionor a subclass of Exceptionmust be called). You cannot catch fatal errors using try/catch.

try/catch块仅适用于抛出的异常(throw ExceptionException必须调用的子类)。您无法使用try/捕获致命错误catch

If your DB connection cannot be established, I would consider it fatal since you probably need your DB to do anything meaningful on the page.

如果您的数据库连接无法建立,我会认为这是致命的,因为您可能需要您的数据库在页面上做任何有意义的事情。

PDOwill throw an exception if the connection cannot be established. Your specific problem is that $dbis not defined when you try to call a method with it so you get a null pointer (sort of) which is fatal. Rather than jump through if ($db == null)hoops as others are suggesting, you should just fix your code to make sure that $dbis either always defined when you need it or have a less fragile way of making sure a DB connection is available in the code that uses it.

PDO如果无法建立连接,将抛出异常。您的具体问题是$db当您尝试使用它调用方法时未定义,因此您会得到一个空指针(某种),这是致命的。而不是if ($db == null)像其他人建议的那样跳过箍,您应该只修复您的代码以确保它$db在您需要时总是被定义,或者有一种不那么脆弱的方式来确保使用它的代码中的数据库连接可用。

If you really want to "catch" fatal errors, use set_error_handler, but this still stops script execution on fatal errors.

如果您真的想“捕获”致命错误,请使用set_error_handler,但这仍然会停止对致命错误的脚本执行。

回答by Hiro

In PHP7, we now can using try catch fatal errorwith simple work

在 PHP7 中,我们现在可以通过简单的工作使用 try catch 致命错误

try {
   do some thing evil
} catch (Error $e) {
   echo 'Now you can catch me!';
}

But usualy, we should avoid using catch Error, because it involve to miss code which is belong to programmer's reponsibility :-)

但是通常,我们应该避免使用 catch Error,因为它会导致遗漏属于程序员责任的代码 :-)

回答by Fifi

I will not report what has already been written about testing if $dbis empty. Just add that a "clean" solution is to artificially create an exception if the connection to the database failed:

如果$db是空的,我不会报告已经写过的关于测试的内容。只需补充一点,“干净”的解决方案是在与数据库的连接失败时人为地创建异常:

if ($db == NULL) throw new Exception('Connection failed.');

Insert the previous line in the try - catchas follow:

将前一行插入try - catch如下:

try{

    // This line create an exception if $db is empty
    if ($db == NULL) throw new Exception('Connection failed.');


    $query = $db->prepare("INSERT INTO users (...) VALUES (...);");
    $query->execute(array(
        '...' => $...,
        '...' => $...
    ));
}
catch(Exception $e){
    $GLOBALS['errors'][] = $e;
}

Hope this will help others!

希望这会帮助其他人!

回答by Kosta

If database connection fails, $dbfrom your first try .. catchblock will be null. That's why later you cannot use a member of non-object, in your case $db->prepare(...). Before using this add

如果数据库连接失败,$db您的第一个try .. catch块将为空。这就是为什么以后你不能使用非对象的成员,在你的情况下$db->prepare(...)。在使用此添加之前

if ($db) {
    // other try catch statement
}

This will ensure that you have db instance to work with it.

这将确保您有 db 实例可以使用它。

回答by Arun Killu

try{
if(!is_null($db))
{
    $query = $db->prepare("INSERT INTO users (...) VALUES (...);");
    $query->execute(array(
        '...' => $...,
        '...' => $...
    ));
}
}
catch(Exception $e){
    $GLOBALS['errors'][] = $e;
}

回答by Ertun?

Try adding the following if statement :

尝试添加以下 if 语句:

if ($db) {
    $query = $db->prepare("INSERT INTO users (...) VALUES (...);");
    $query->execute(....);
}
else die('Connection lost');