Req #32100 [Com]: Request 'finally' support for exceptions

From: Date: Wed, 25 Apr 2012 20:32:34 +0000
Subject: Req #32100 [Com]: Request 'finally' support for exceptions
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-169939@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=32100&edit=1

 ID:                 32100
 Comment by:         toplegocreator at hotmail dot com
 Reported by:        ceefour at gauldong dot net
 Summary:            Request 'finally' support for exceptions
 Status:             Closed
 Type:               Feature/Change Request
 Package:            Feature/Change Request
 Operating System:   *
 PHP Version:        5.*
 Block user comment: N
 Private report:     N

 New Comment:

"Though this is still possible (however much more to type) it is wrong design. Since obviously
you are using the exceptions as control flow."

If exceptions should never be propagated up the stack to a block of code that knows how to deal with
them, why are exceptions there in the first place? Exceptions ARE flow control. That's their
reason for existing. If they shouldn't be used that way, they shouldn't be included in the
language.

Let me elaborate. An exception should occur any time when the current block cannot successfully
continue execution in the current state and has no direct means (or shouldn't have any direct
means because of good separation of concerns) of informing the client of the problem. A finally
clause, while not strictly needed if code repetition is acceptable (and it isn't in my book),
is appropriate for ensuring that resources (like database connections, open files, a printer,
whatever) are released when fatal errors occur. Trying to deal with the error as some kind of
returned result all the way up the stack will just make your code more difficult to read and
maintain; an error should go all the way up the stack until a piece of code that's responsible
for output can determine how to inform the client. That's how exceptions are supposed to be
used, and a finally clause makes it possible to properly and (fairly) reliably release resources,
which is also a best practice.


Previous Comments:
------------------------------------------------------------------------
[2012-04-19 20:00:39] simon at stienen dot name

RAII is an elegant solution for tidying up scopes reliably.
It is also possible in PHP to do RAII without writing one class per resource type:

<?php

class ScopeGuard {
    private $callback;

    function __construct($callback) {
        $this->callback = $callback;
    }

    function __destruct() {
        if (is_callable($this->callback)) {
            call_user_func($this->callback);
        }
    }
}

function do_something() {
    mysql_query("LOCK TABLES mytable WRITE");
    $guard = new ScopeGuard(function() {
        mysql_query("UNLOCK TABLES");
    });

    try {
        // ... do lots of queries here
    }
}

?>

$guard will be destructed when leaving the do_something - either by throwing an exception or by
exiting the function normally.

HOWEVER: RAII in C++ (which neither employs nor needs a finally keyword) is more subtle - or rather:
Scopes are. In PHP you can define a variable within a loop or a conditional block - and use it
afterwards. In C++ you can't. A variable defined inside a certain block will be destroyed once
the block is left. Consider the following example:

<?php

function do_something() {
    if (foo) {
        mysql_query("LOCK TABLES mytable WRITE");
        $guard = new ScopeGuard(function() {
            mysql_query("UNLOCK TABLES");
        });

        try {
            // ... do lots of queries here
        }

        // *1*
    }

    do_something_else();

    // *2*
}

?>

In C++, this would work as expected of a "finally" replacement and unlock the tables at
*1*, when the if scope closes. In PHP however, $guard will only be destroyed when leaving the
function at *2*. This can be fixed by manually adding an unset($guard) at *1*, but this is inelegant
and error prone.

So, while I have never needed finally, I think the way PHP works and is used absolutely validates
its introduction as a useful addition to the language. The alternative would be to introduce C/++
style closed scopes, but those would most likely not only break a lot of existing code, but the
coders as well, as they do not even remotely fit into the way PHP is written.

------------------------------------------------------------------------
[2012-04-12 15:42:21] matthias at die-legendaeren dot de

"Just going to say 'Me too!'? Don't clutter the database with that please
!"

But this is the right place for a "me too": to prove that a statement from 12 
years ago was shortsighted and in a "works for me" way, developers (as customers) 
who disagree have to group behind their request.

------------------------------------------------------------------------
[2012-04-11 21:21:33] gudjonj at gmail dot com

+1 for finally in PHP

------------------------------------------------------------------------
[2012-04-11 08:34:13] ravilov at gmail dot com

My two cents...

Here's an example of emulating "finally" in PHP without needing to duplicate code.


$_ex = null;
AllocateSomeResource();
try {
    DoSomeProcessing();
} catch (Exception $ex) {
    $_ex = $ex;
}
DeallocateSomeResource();
if ($_ex != null) {
    throw $_ex;
}


That said, I completely agree any current workaround/emulation/"solution" is nothing but
cumbersome and bug-prone, and that we shouldn't have to come up with such creative ways to
overcome what seems like a language design flaw. PHP is a tool, it is supposed to work *with* us,
not *against* us.

------------------------------------------------------------------------
[2012-04-03 13:08:00] andrew dot feller at gmail dot com

The demand for "finally" is a symptom of PHP not officially and explicitly addressing
supported solutions to managing resources.  I cannot find anything within PHP documentation to
address this:

http://www.php.net/manual/en/language.oop5.decon.php
http://www.php.net/manual/en/faq.misc.php

So I recommend to move beyond inclusion of finalizers and start with educating constituents because
there is an opportunity to resolve this and hopefully improve quality of work done by developers

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=32100


-- 
Edit this bug report at https://bugs.php.net/bug.php?id=32100&edit=1


Thread (53 messages)

« previous php.bugs (#169939) next »