บทนำ
พฤติกรรมพิเศษของ Finally Block เมื่อ Try หรือ Catch (หรือทั้งคู่) มี Return Statement ปกติ Return จะคืน Control กลับไปยัง Caller แต่ใน Function ที่มี Try/Catch/Finally พร้อม Return Statement ใน Finally จะ Execute ก่อน Return
ตัวอย่าง
Function div() มี Try-Catch-Finally Try Block Return ผลหาร Catch Block Return Error Message แต่ Finally Execute ก่อน:
<?php
function div($x, $y) {
try {
if ($y == 0) {
throw new Exception("Division by 0");
} else {
$res = $x / $y;
return $res;
}
} catch (Exception $e) {
return $e->getMessage();
} finally {
echo "This block is always executed\n";
}
}
$x = 10;
$y = 0;
echo div($x, $y);
?>
ผลลัพธ์
This block is always executed Division by 0
เปลี่ยน $y = 5
This block is always executed 2
รายละเอียดการทำงาน
- Try Block Execute → พบ Return Statement
- Return Value ถูกเก็บไว้ชั่วคราว
- Finally Block Execute
- คืนค่าที่เก็บไว้ให้ Caller
ลำดับเดียวกันสำหรับ Catch Block ที่มี Return
ตัวอย่าง: Finally Override Return
Finally Block ที่มี Return จะ Override Return จาก Try/Catch:
<?php
function test() {
try {
return "from try";
} finally {
return "from finally";
}
}
echo test(); // "from finally"
?>
ข้อควรระวัง
- Finally Block ที่มี Return จะ Override Return อื่นทั้งหมด
- ไม่ควรใส่ Return ใน Finally เว้นแต่จงใจ
- Finally ใช้สำหรับ Cleanup (Close Resources, Unlock, Log) เป็นหลัก
- Exception ใน Finally จะแทนที่ Exception เดิม (ถ้ามี)
Best Practice
<?php
function safeDivide($x, $y) {
$resource = acquireResource();
try {
if ($y == 0) throw new Exception("Division by zero");
return $x / $y;
} catch (Exception $e) {
logError($e);
throw $e; // Re-throw
} finally {
releaseResource($resource); // Cleanup only - NO RETURN
}
}
?>