try-catch and where's finally?

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
x_mutatis_mutandis_x
Forum Contributor
Posts: 160
Joined: Tue Apr 17, 2012 12:57 pm

try-catch and where's finally?

Post by x_mutatis_mutandis_x »

Coming from a JAVA background, I have always loved the "finally" block in the try/catch logic and in my opinion is the most important block of the group. I wonder why PHP doesn't define the "finally" block. Is there a particular reason why finally wasn't introduced along with try/catch?

A code can get as simple as this:

Code: Select all

try {
        ....
} catch (Exception $e) {
        ....
        throw new MyApplicationException($e);       
} finally {
         //{this gets called irrespective of exception or not, so you can do something like debug or trace level logging, freeing up resources}
}
Instead, without 'finally' you would have to do something like (duplication):

Code: Select all

try {
        //....
} catch (Exception $e) {
        //....
        //{this gets called irrespective of exception or not, so you can do something like debug or trace level logging, freeing up resources}
        throw new MyApplicationException($e);       
} 
//{this gets called irrespective of exception or not, so you can do something like debug or trace level logging, freeing up resources}
What if the code in "{this gets called irrespective of exception or not, so you can do something like debug or trace level logging, freeing up resources}" throws an exception that you wanna handle, see where I'm getting at?
User avatar
tr0gd0rr
Forum Contributor
Posts: 305
Joined: Thu May 11, 2006 8:58 pm
Location: Utah, USA

Re: try-catch and where's finally?

Post by tr0gd0rr »

The choice to exclude finally seems to be an argument about the purpose of exceptions and their role in flow control. See this comment on a bug report request from 2005. There are some other good comments there as well.

If you are worried about freeing up resources, the normal pattern is to use the `__destruct` magic method. A lot of PHP classes use them to close file handles, sql resources, sql transactions etc. because `__destruct` methods will be called sometime after the Exception, when objects are destroyed.

Specifically in dealing with file and sql resources, php will automatically free them up at the end of the script anyway unless there is a segmentation fault which is really rare.
x_mutatis_mutandis_x
Forum Contributor
Posts: 160
Joined: Tue Apr 17, 2012 12:57 pm

Re: try-catch and where's finally?

Post by x_mutatis_mutandis_x »

Thanks for link. The reasoning is same as I mentioned above (code duplication). Another reason why finally would be helpful is when a function can choose not to catch an exception (without getting the "Uncaught Exception Error") but yet execute a block of code no matter what, whether an exception is thrown or not (I guess it was mentioned in one of the comments in the link, but I'm not sure). An example about what I mean:
RecordDAO.php

Code: Select all

class RecordDAO {
     private $daoFactory;
    /**
     * @throws PDOException
     */
    public function fetchByFilter(stdClass $filter) {
           $query = "....";
           try {
                 $this->daoFactory()->query($query);
                 ...
           } finally {
                   $log->debug("Debugging query: \n$query");
           }
    }

}
BusinessLogicClass.php

Code: Select all

class BusinessLogicClass {
       
         public function processRecords(stdClass $filter) {
                 $daoFactory = DAOFactory::getInstance();
                 try {
                         $data = $daoFactory->getRecordDAO()->fetchByFilter($filter);
                          //process data here 
                          
                  } catch (PDOException $pdoEx) {
                          throw new BusinessLogicException($pdoEx);
                  } finally {
                         try {
                                $daoFactory->closeConnection();
                         } catch (PDOException $ex) {
                               //you can re throw another exception here or just consume it
                         }
                  }
         }

}
So instead of catching the exception in every function in DAO class and propogating it to the caller (or worry about handling it), I just catch the one exception in a function in the business logic class (which may also call more DAO class functions), and yet at the same time I can safely log the query in debug mode in my DAO class.

tr0gd0rr wrote:If you are worried about freeing up resources, the normal pattern is to use the `__destruct` magic method. A lot of PHP classes use them to close file handles, sql resources, sql transactions etc. because `__destruct` methods will be called sometime after the Exception, when objects are destroyed.
__destruct() is pretty much like the java.lang.Object.finalize(). But you are putting your faith on when the object gets destroyed (ideally done as soon as when a reference is lost). Plus I don't think objects gets destroyed after an exception is thrown, unless it finally causes the script to terminate (if its an uncaught exception), or the object's scope is local to the function. If a reference to the object exists, it should not be destroyed.
Specifically in dealing with file and sql resources, php will automatically free them up at the end of the script anyway unless there is a segmentation fault which is really rare.
Thats true, but again you are waiting for it to happen.
kon
Forum Newbie
Posts: 19
Joined: Sat Mar 03, 2012 5:43 am

Re: try-catch and where's finally?

Post by kon »

PHP is not Java … don’t get me wrong Java didn’t discovered OOP, but for me working with Java 12 hours a day for many years made me thing in an OOP way. Of course the finally clause is not in the OOP core. Finally with PHP is the logical way to go … that the program will executed and that the exception will not be thrown … so the question might be why there is finally in Java …
x_mutatis_mutandis_x
Forum Contributor
Posts: 160
Joined: Tue Apr 17, 2012 12:57 pm

Re: try-catch and where's finally?

Post by x_mutatis_mutandis_x »

kon wrote:PHP is not Java … don’t get me wrong Java didn’t discovered OOP, but for me working with Java 12 hours a day for many years made me thing in an OOP way. Of course the finally clause is not in the OOP core. Finally with PHP is the logical way to go … that the program will executed and that the exception will not be thrown … so the question might be why there is finally in Java …
Well this has nothing to do with OOP. You can have try/catch in procedural PHP as well, exceptions traverse through the caller function's stack, just like JAVA's method's stack, objects do not come into picture at all.

Ofcourse JAVA didn't discover OOP. In JAVA when you have objects staying alive, accessed by different async. threads, and if you are accessing a resource (from a pool) in one thread, you need to free it up (or release to the pool) properly when the thread releases the lock on the object, before another thread can access the resource again ( probably the same from a pool) to the resource. Finally helps you do that pretty easily, rather than code duplication everywhere and putting that responsibiliy on the programmer to make sure you duplicate it in catch block and outside of it, or make sure you consume the exceptions.

PHP objects on the other hand have the life time of script's execution. So the above scenario will never happen, and basically "finally" would be more of convinience than a necessity. All I was asking is was there a logical reason (other than to simplify coding) as to why it wasn't introduced to PHP. I think I already got the answer from the link in the post by "tr0gd0rr". According to the PHP dev. who responded, they were just lazy because its not necessary.

And on the other hand he advises not to use exceptions as control-flow, by rethrowing exceptions, but instead consume/handle the exception (or a comment '//do nothing' <---- I hate those comments) and write the "finally" block of code after try/catch blocks which ofcourse is same as in the "finally" block. Well then, extending "Exception" class and creating your own exceptions is pointless..
User avatar
tr0gd0rr
Forum Contributor
Posts: 305
Joined: Thu May 11, 2006 8:58 pm
Location: Utah, USA

Re: try-catch and where's finally?

Post by tr0gd0rr »

You're right. It seems like there is no truly good reason to omit `finally` from PHP. I would certainly vote to put it in.
Post Reply