4

There is this question that I found:

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

If you can add anything to it then please do as I am new to PDO, also what does this mean;

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

On the MySQL website it says "ensures the creation of exceptions rather than errors" but I do not understand this, can anyone please elaborate on it please.

Community
  • 1
  • 1
Basic
  • 1,818
  • 5
  • 21
  • 31

2 Answers2

4

Exceptions are catchable via try/catch and are classes with properties, while proceedural errors cannot and are not. Proceedural errors are instead handled by PHP's native error handling.

You can observe the behavior difference by manually triggering them.

to throw an Exception:

throw new Exception();

to trigger a proceedural error:

trigger_error($message, U_USER_ERROR);

Exceptions are bassically the OO way of error handling. Find more information about Exceptions here: http://php.net/manual/en/language.exceptions.php

dqhendricks
  • 19,030
  • 11
  • 50
  • 83
1

Well, they are pretty similar. In PHP native error handling you can trow your own errors with trigger_error($error, [$level]) as you can throw your own exceptions with throw new MyException($error); you can set a default error handler with set_error_handler() which will manage all PHP error (except parsing) your own way as you can set a default exception handler with set_exception_handler(). Both PHP native errors and exceptions are automatically triggered/thrown somehow: PHP native errors compiling the script, exceptions if you are using specific items such as (PDO) or something.

Now let's try the same code with different approaches: With PHP native errors you can do things such as:

$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);

I think this does not really need any explanation. If an error is triggered, the entire script is skipped and you see the error. There are no more things you can do; you could set E_USER_ERROR or E_USER_NOTICE or E_USER_WARNING and handle them differently, but you have not that big choice. Now take a look at a possible OOP approach with try{} catch() {} blocks:

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();
}

The main difference is that if the first try{} block throw an exception the second try{} will be executed any way. In fact if an exception is thrown, only the rest of the script inside that try{} block will be skipped.

Another difference (the one i love most) is that you can create several classes (extending mains Exception or PDOException or others) and customize very much your error handling behavior. You have unlimited possibilities to customize your classes, adding functions, editing already existing ones. You can add specific function (such as $e->fileGenerate();) and call them inside the catch() {} block where needed.

Notice also that if you want your entire script to stop if an error occurred, means that that error needs trigger_error(); instead if you want that an error only stops a specific block of code related to that error then it's time for try and catch.

You should not use one replacing the other, you should use one beside the other evaluating each errors as it is.

By the way PDO::setAttribute() change default values and options in your database handler. You can for example change your default fetch (used in PDOStatement::fetch()) with $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);.

References:

Shoe
  • 74,840
  • 36
  • 166
  • 272
  • Worth mentioning that E_USER_WARNING and E_USER_NOTICE will not exit your script. Also, if you set your own error handler ([set_error_handler](http://php.net/set_error_handler)), it's completely up to you if any error will exit your script. – DanMan Apr 17 '11 at 10:10
  • Really good example thanks.. I have a question - how did you create customFunction() function in the DBEx catch block? – I'll-Be-Back Feb 12 '12 at 21:55
  • @user791022, you have to create the class and extend the main Exception class with: `class MyException extends Exception {}`. Inside the class you can define custom functions/methods. – Shoe Feb 12 '12 at 23:35
  • @JeffPigarelli thanks! Could you look at my question please at http://stackoverflow.com/questions/9252276/how-to-use-try-catch-block-for-pdo and how would you do it? – I'll-Be-Back Feb 12 '12 at 23:56