Skip to content

PHP Tutorial Error Handling

The finally Block

Lesson 190 of 369 2 min read By Deepak Paswan Updated Oct 5, 2026

A finally block runs no matter what happens in the try: success, an exception, or even a return. It is the right place for cleanup.

index.php
PHP
<?php
function work(bool $fail): void
{
    try {
        echo "Start\n";

        if ($fail) {
            throw new RuntimeException("boom");
        }

        echo "Done\n";
    } catch (RuntimeException $e) {
        echo "Caught: " . $e->getMessage() . "\n";
    } finally {
        echo "Cleanup\n";
    }
}

work(false);
echo "---\n";
work(true);
Output
OUTPUT
Start
Done
Cleanup
---
Start
Caught: boom
Cleanup

Cleanup is printed in both cases.

A typical use: close what you opened

index.php
PHP
<?php
$handle = fopen("data.txt", "w");

try {
    fwrite($handle, "important data");
    throw new RuntimeException("something went wrong while writing");
} catch (RuntimeException $e) {
    echo "Error: " . $e->getMessage() . "\n";
} finally {
    fclose($handle);
    echo "File closed";
}
Output
OUTPUT
Error: something went wrong while writing
File closed

Without finally, an exception could skip fclose() and leave the file open.

try and finally without catch

You can use finally alone. The exception still travels upward, but the cleanup runs first.

index.php
PHP
<?php
function risky(): void
{
    try {
        throw new LogicException("not handled here");
    } finally {
        echo "Cleaning up\n";
    }
}

try {
    risky();
} catch (LogicException $e) {
    echo "Caught outside: " . $e->getMessage();
}
Output
OUTPUT
Cleaning up
Caught outside: not handled here

finally and return

finally runs even when the try has already hit return.

index.php
PHP
<?php
function test(): string
{
    try {
        return "from try";
    } finally {
        echo "finally runs first\n";
    }
}

echo test();
Output
OUTPUT
finally runs first
from try
dangerous
A return inside finally wins
If finally itself contains return, it replaces the earlier return and swallows exceptions. Avoid return and throw inside finally unless you are sure.

Common uses

  • Close files, database connections or locks.
  • Release a lock (flock($h, LOCK_UN)).
  • Roll back a database transaction when something fails.
  • Remove temporary files.
index.php
PHP
<?php
$lock = fopen("job.lock", "c");
flock($lock, LOCK_EX);

try {
    echo "Doing exclusive work\n";
} finally {
    flock($lock, LOCK_UN);
    fclose($lock);
}
Output
OUTPUT
Doing exclusive work
lightbulb
Not every cleanup needs finally
PHP frees memory and closes files at the end of the script. Use finally when cleanup matters before the script ends, such as locks and transactions.