尝试在PDO和其他一些事情中捕获vs if else

时间:2011-04-15 23:57:29

标签: php mysql pdo

我找到了这个问题:

What is the advantage of using try {} catch {} versus if {} else {}

如果您可以添加任何内容,那么请像我对PDO的新手那样做,这也意味着什么;

$dbc->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

在MySQL网站上,它说“确保创建例外而不是错误”但我不明白这一点,任何人都可以请详细说明。

2 个答案:

答案 0 :(得分:4)

可以通过try / catch捕获异常,并且是具有属性的类,而不是也可能不是。而程序错误则由PHP的本机错误处理来处理。

您可以通过手动触发它们来观察行为差异。

抛出异常:

throw new Exception();

触发意外错误:

trigger_error($message, U_USER_ERROR);

例外是错误处理的OO方式。在此处查找有关例外的更多信息:http://php.net/manual/en/language.exceptions.php

答案 1 :(得分:1)

嗯,他们非常相似。在PHP本机错误处理中,您可以使用trigger_error($error, [$level])来设置自己的错误,因为您可以使用throw new MyException($error)抛出自己的异常;您可以使用set_error_handler()设置默认错误处理程序,它将管理您自己的所有PHP错误(解析除外),因为您可以使用set_exception_handler()设置默认异常处理程序。 PHP本机错误和异常都会以某种方式自动触发/抛出:编译脚本的PHP本机错误,如果您使用(PDO)等特定项目,则会出现异常。

现在让我们尝试使用不同方法的相同代码: 使用PHP本机错误,您可以执行以下操作:

$db = new Database();
if ($db === NULL) { trigger_error("Cannot connect to the database", E_USER_ERROR); }

$result = $db->query("UPDATE charlieiscool SET iloveunicorns = 1 WHERE userid = 1");
if (!$result) { trigger_error("Error updating table", E_USER_ERROR); }

$file = 'log.php';
if (!file_exists($file) or !file_get_contents($file)) { trigger_error("$file not found", E_USER_ERROR); }
require($file);

我认为这并不需要任何解释。如果触发错误,则跳过整个脚本,您将看到错误。你无能为力;您可以设置E_USER_ERRORE_USER_NOTICEE_USER_WARNING并以不同方式处理它们,但您没有那么大的选择。现在看看使用try{} catch() {}块的可能的OOP方法:

try {
    $db = new Database();
        if (!$db) { throw new DBEx("Cannot connect to the database"); }
    $result = $db->query("UPDATE charlieiscool SET iloveunicorns = 1 WHERE userid = 1");
        if (!$result) { throw new QueryEx("Query failed"); }
} catch (PDOException $e) {
    echo $e->getMessage();
} catch (DBEx $e) {
    $e->customFunction();
} catch (QueryEx) {
    $e->customFunctionForQuery();
}

try {
    $file = 'log.php';
    if (!file_exists($file) or !file_get_contents($file)) { throw new FileEx("$file does not exists"); }
    require($file);
} catch (FileEx) {
    $e->fileGenerate();
    $e->logError();
}

主要区别在于,如果第一个try{}块抛出异常,则第二个try{}将以任何方式执行。实际上,如果抛出异常,则只会跳过try{}块内的其余脚本。

另一个区别(我最喜欢的那个)是你可以创建几个类(扩展主管ExceptionPDOException或其他)并自定义你的错误处理行为。您可以无限制地自定义类,添加功能,编辑现有类。您可以添加特定功能(例如$e->fileGenerate();)并在需要的catch() {}块内调用它们。

另请注意,如果您希望在发生错误时停止整个脚本,则表示该错误需要trigger_error();相反,如果你想要一个错误只停止一个与该错误相关的特定代码块,那么就该尝试并捕获它。

你不应该使用一个替换另一个,你应该使用另一个来评估每个错误。

顺便提一下PDO::setAttribute()更改数据库处理程序中的默认值和选项。例如,您可以使用PDOStatement::fetch()更改默认提取(在$dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);中使用)。

参考文献: