I know what exceptions are and I know when to use them but today, I read from this blog Destructing PHP. It has the below code
require('autoload.php');
function foo($db, $data) {
$db->beginTransaction();
foreach ($data as $row) {
$db->insert($row);
}
$db->commit();
}
$db = db::factory();
$data = data::factory();
try {
foo($db, $data);
} catch (Exception $e) {}
$db->insert(data::finalData());
According to the program the data::finalData() should be stored independently from whether foo() succeeds or not. Unfortunately this isn't the case: If something in the loop inside foo() throws there will be an open transaction. The final data now becomes part of that transaction. As there is no further handling PHP will clean-up at the end of this program and automatically rewind the transaction.
The confusing part is The final data now becomes part of that transaction.
This conflicts with my understanding of exceptions, I have known exceptions to start execution from where throw was called when there are caught, in this case somewhere in the foreach and continue to the end of foo function executing $db->commit() along effectively closing the DB transaction.
With this observation, final data should never become part of transaction like the author says.
The commit directive is last in function foo(). If an exception is raised (that can only happen inside the function since the try-catch block only contains the call to that function), then that functions code is not processed to the end, obviously. So no commit is performed, the transaction "hangs".
Execution proceeds in the catch block (which is empty, so the exception is "swallowed") and then goes on normally just after the catch block and executes the "final data" directive. So the commit directive in the function is never executed, the transaction still accepts statements. That is why the "final data" gets part of that transaction.
Execution does not somehow jump back after an exception has been caught! That is the whole point of an exception: to immediately leave the failing code and return to the calling / controlling scope.