28

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

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

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

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

这是问题所在:

  • 当与数据库的连接正常时,一切正常,
  • 当连接失败但我不使用数据库时,我有$GLOBALS['errors'][]数组,之后脚本仍在运行,
  • 当与数据库的连接失败时,我收到以下致命错误:

注意:未定义变量:第 32 行 C:\xampp\htdocs[...]\test.php 中的 db

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

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

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

谢谢您的帮助!

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

4

6 回答 6

38

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

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

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

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

于 2012-10-17T06:55:10.023 回答
33

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

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

但是通常情况下,我们应该避免使用catch Error,因为它涉及错过属于程序员责任的代码:-)

于 2018-08-04T17:29:49.810 回答
1

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

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

将上一行插入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;
}

希望这对其他人有帮助!

于 2018-01-21T10:48:23.007 回答
0

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

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

这将确保您有数据库实例可以使用它。

于 2012-10-17T06:46:20.557 回答
-1

尝试添加以下 if 语句:

if ($db) {
    $query = $db->prepare("INSERT INTO users (...) VALUES (...);");
    $query->execute(....);
}
else die('Connection lost');
于 2012-10-17T06:45:26.690 回答
-1
try{
if(!is_null($db))
{
    $query = $db->prepare("INSERT INTO users (...) VALUES (...);");
    $query->execute(array(
        '...' => $...,
        '...' => $...
    ));
}
}
catch(Exception $e){
    $GLOBALS['errors'][] = $e;
}
于 2012-10-17T06:49:50.993 回答