Before 5.5, releasing a resource on every exit path meant writing the release twice — once at the end of try and once inside a catch that rethrows. finally removes the duplication, and the part worth understanding is what it does to a return that has already been evaluated.
function tag()
{
$label = 'try';
try {
return $label;
} finally {
$label = 'finally'; // too late: the value was already taken
echo "cleanupn";
}
}
echo tag(); // prints cleanup, then try
function swallowed()
{
try {
throw new RuntimeException('import failed');
} finally {
return 'ok'; // the exception is discarded here
}
}
The return expression is evaluated on the way into finally, so reassigning the variable afterwards changes nothing — which is the behaviour you want, because it means cleanup cannot corrupt a result by accident. The second function is the trap: a return inside finally replaces whatever was pending, an in-flight exception included, and that is the quietest way there is to lose a stack trace. The honest use has no catch at all — acquire, work in try, release in finally, and let the exception continue to whoever is actually equipped to decide about it.