A finally block runs after try or catch, so cleanup can happen in one place.

always runs Use finally for cleanup-like state that should happen after success or recovery.

Finally Cleanup

mode
finally_cleanup.php
Replay: real traced execution (multi-file project)
<?php
$mode = "save";
$closed = "no";

try {
    if ($mode !== "save") {
        throw new Exception($mode);
    }

    $status = "saved";
} catch (Exception $error) {
    $status = "recovered_" . $error->getMessage();
} finally {
    $closed = "yes";
}

echo "mode=" . $mode . "\n";
echo "status=" . $status . "\n";
echo "closed=" . $closed . "\n";
<?php
$mode = "fail";
$closed = "no";

try {
    if ($mode !== "save") {
        throw new Exception($mode);
    }

    $status = "saved";
} catch (Exception $error) {
    $status = "recovered_" . $error->getMessage();
} finally {
    $closed = "yes";
}

echo "mode=" . $mode . "\n";
echo "status=" . $status . "\n";
echo "closed=" . $closed . "\n";
<?php
$mode = "retry";
$closed = "no";

try {
    if ($mode !== "save") {
        throw new Exception($mode);
    }

    $status = "saved";
} catch (Exception $error) {
    $status = "recovered_" . $error->getMessage();
} finally {
    $closed = "yes";
}

echo "mode=" . $mode . "\n";
echo "status=" . $status . "\n";
echo "closed=" . $closed . "\n";
  1. $mode ← save, $closed ← no, $status ← saved

    1<?php2$mode→ save = "save"; //@mode="fail", "retry"3$closed→ no = "no";45try {6    if ($mode !== "save") {7        throw new Exception($mode);8    }910    $status→ saved = "saved";11} catch (Exception $error) {12    $status = "recovered_" . $error->getMessage();13} finally {14    $closed = "yes";15}1617echo "mode=" . $modesave . "\n";18echo "status=" . $statussaved . "\n";19echo "closed=" . $closedyes . "\n";
    outputmode=save
    status=saved
    closed=yes
  1. $mode ← fail, $closed ← no

    1<?php2$mode→ fail = "fail";3$closed→ no = "no";
  2. if ($mode !== "save")

    5try {6    if ($modefail !== "save") {7        throw new Exception($modefail);8    }
  3. echo "mode=" . $mode . " ";

    11} catch (Exception $error) {12    $status = "recovered_" . $error->getMessage();13} finally {14    $closed = "yes";15}1617echo "mode=" . $modefail . "\n";18echo "status=" . $statusrecovered_fail . "\n";19echo "closed=" . $closedyes . "\n";
    outputmode=fail
    status=recovered_fail
    closed=yes
  1. $mode ← retry, $closed ← no

    1<?php2$mode→ retry = "retry";3$closed→ no = "no";
  2. if ($mode !== "save")

    5try {6    if ($moderetry !== "save") {7        throw new Exception($moderetry);8    }
  3. echo "mode=" . $mode . " ";

    11} catch (Exception $error) {12    $status = "recovered_" . $error->getMessage();13} finally {14    $closed = "yes";15}1617echo "mode=" . $moderetry . "\n";18echo "status=" . $statusrecovered_retry . "\n";19echo "closed=" . $closedyes . "\n";
    outputmode=retry
    status=recovered_retry
    closed=yes