Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> PHP

Exception Handling กับ Finally ใน PHP

บทนำ

โค้ดใน Finally Block จะ Execute เสมอ ไม่ว่าจะมี Exception ใน Try Block หรือไม่ Block นี้อยู่หลัง Catch Block หรือแทน Catch Block ก็ได้

1. Catch และ Finally ทั้งคู่

ถ้ามี Exceptionใน Try → ทั้ง Catch และ Finally รัน ถ้าไม่มี Exception → แค่ Finally รัน:

<?php
function div($x, $y) {
    if (!$y) {
        throw new Exception('Division by zero.');
    }
    return $x / $y;
}

try {
    echo div(10, 0) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ', $e->getMessage(), "\n";
} finally {
    echo "This block is always executed\n";
}

echo "Execution continues\n";
?>

ผลลัพธ์ (มี Exception)

Caught exception: Division by zero.
This block is always executed
Execution continues

ไม่มี Exception (div(10, 5))

<?php
try {
    echo div(10, 5) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ', $e->getMessage(), "\n";
} finally {
    echo "This block is always executed\n";
}
echo "Execution continues\n";
?>

ผลลัพธ์

2
This block is always executed
Execution continues

2. Finally Block เพียงอย่างเดียว (ไม่มี Catch)

Try Block เรียก Function ที่ Throw Exception:

<?php
function div($x, $y) {
    try {
        if (!$y) {
            throw new Exception('Division by zero.');
        }
        return $x / $y;
    } catch (Exception $e) {
        echo 'Caught exception: ', $e->getMessage(), "\n";
    }
}

try {
    echo div(10, 0) . "\n";
} finally {
    echo "This block is always executed\n";
}

echo "Execution continues\n";
?>

ผลลัพธ์

Caught exception: Division by zero.
This block is always executed
Execution continues

Use Cases ของ Finally

  • Resource Cleanup - fclose(), mysqli_close(), unlock()
  • Logging - Log การสิ้นสุด Operation
  • Reset State - Reset Flags, Counters
  • Transaction Cleanup - Rollback/Commit

ตัวอย่างจริง: Database Connection

<?php
function getUserData($id) {
    $pdo = new PDO($dsn, $user, $pass);
    $stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
    
    try {
        $stmt->execute([$id]);
        return $stmt->fetch();
    } finally {
        $stmt = null;      // Close Statement
        $pdo = null;       // Close Connection
    }
}
?>

สรุป

ScenarioCatch Runs?Finally Runs?
No ExceptionNoYes
Exception CaughtYesYes
Exception Not CaughtNoYes
Return in Try/CatchYes/NoYes (before return)