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

 ID:                 32100
 Comment by:         jl235 at kent dot ac dot uk
 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:

Most of the exceptions people come across in their PHP code tends to be for 
either File IO, or database access. Both of these need a finally to ensure the 
handle/connection/whatever gets closed, or dealt with in some other way. Using 
try/catch is already a lot more cumbersome then a world without Exceptions, but 
without finally, it adds a lot duplication and state management.

For example in my own code I do something along the lines of ...

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

$time = microtime( true );
$sql = generateSQLQuery();
$conn = openDBConnection();
$ex = null;

try {
    $result = runSQLQuery( $conn, $sql );
} catch ( Exception $ex ) { /* do nothing */ }

closeDBConnection( $conn );
logSQLQuery( $sql, microtime(true) - $time );

if ( $ex !== null ) {
    throw $ex;
}

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

... which could just be ...

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

$time = microtime( true );
$sql  = generateSQLQuery();
$conn = openDBConnection();

try {
    $result = runSQLQuery( $conn, $sql );
} finally {
    closeDBConnection( $conn );
    logSQLQuery( $sql, microtime(true) - $time );
}

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

Simpler to write, easier to read, harder to get wrong, and more elegant.

Please re-open this.


Previous Comments:
------------------------------------------------------------------------
[2012-06-05 11:19:41] sgnezdov at fastmail dot fm

Finally is absolutely necessary for proper management of disposable resources.

There is no easy to read workaround for

try { 
 causeException();
} finally {
 releaseResource();
}

others pointed out that solving this issue kills re-throw, which is equally 
important.

------------------------------------------------------------------------
[2012-05-29 21:36:49] kavi at postpro dot net

Since every other kitchen sink on the planet has been thrown into PHP, why not 
also the refrigerator which we all expect to be here?  Come on.  At least give 
a 
good reason.

Quoting topaz:

"Ugly workaround hack time!

(This is not a substitute for a real language feature!)"


...yeah, you're actually describing the *entire language* there. :|

------------------------------------------------------------------------
[2012-04-25 20:32:33] toplegocreator at hotmail dot com

"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.

------------------------------------------------------------------------
[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.

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


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

Reply via email to