Skip to main content

เนื้อหาภาษาไทย / Thai content

System guide Content reviewed

การจัดการ Exceptions: Try-Catch Blocks

บทความนี้กล่าวถึงความสำคัญของการจัดการ Exceptions ใน PHP เพื่อรับมือกับข้อผิดพลาดที่อาจเกิดขึ้นใน Application โดยแนะนำการใช้ Try-Catch Blocks เพื่อดักจับและจัดก...

การจัดการ Exceptions: Try-Catch Blocks

ในบทที่แล้ว เราได้เรียนรู้เกี่ยวกับการ Logging เพื่อบันทึกเหตุการณ์ต่างๆ ที่เกิดขึ้นใน Application ของเรา แต่เมื่อเกิดข้อผิดพลาดหรือเหตุการณ์ที่ไม่คาดฝัน การบันทึก Log เพียงอย่างเดียวอาจไม่เพียงพอ เราจำเป็นต้องมีการจัดการ Exceptions เพื่อให้ Application ของเราสามารถรับมือกับปัญหาเหล่านั้นได้อย่างสง่างาม ไม่ให้ Application หยุดทำงานกลางคัน และยังสามารถแจ้งเตือนผู้ใช้งานหรือผู้ดูแลระบบได้อย่างเหมาะสม

บทนี้จะพาคุณไปทำความเข้าใจกับการจัดการ Exceptions ใน PHP ด้วย Try-Catch Blocks ซึ่งเป็นเครื่องมือพื้นฐานแต่ทรงพลังในการจัดการข้อผิดพลาด

Exceptions คืออะไร?

Exception คือเหตุการณ์ที่เกิดขึ้นระหว่างการทำงานของโปรแกรม ซึ่งเป็นการรบกวนการทำงานตามปกติของโปรแกรม เหตุการณ์เหล่านี้อาจเกิดจากหลายสาเหตุ เช่น การพยายามเข้าถึงไฟล์ที่ไม่มีอยู่จริง, การหารด้วยศูนย์, หรือการเรียกใช้ฟังก์ชันที่ไม่ถูกต้อง

ใน PHP, Exceptions คือ Objects ที่สืบทอดมาจากคลาส Exception (หรือคลาสย่อยอื่นๆ ของ Exception) ซึ่งมีข้อมูลเกี่ยวกับข้อผิดพลาดที่เกิดขึ้น

การใช้ Try-Catch Blocks

Try-Catch Blocks เป็นโครงสร้างการควบคุมที่ใช้ในการจัดการ Exceptions ใน PHP โครงสร้างนี้ประกอบด้วยสองส่วนหลัก:

  • Try Block: ส่วนของโค้ดที่เราคาดว่าจะเกิด Exception
  • Catch Block: ส่วนของโค้ดที่จะทำงานเมื่อ Exception เกิดขึ้นใน Try Block

รูปแบบการใช้งาน Try-Catch Blocks เป็นดังนี้:

try {
  // โค้ดที่อาจทำให้เกิด Exception
  $result = 10 / 0; // ตัวอย่าง: การหารด้วยศูนย์
  echo "ผลลัพธ์: " . $result; // บรรทัดนี้จะไม่ถูกเรียกใช้หากเกิด Exception ก่อน
} catch (Exception $e) {
  // โค้ดที่จะทำงานเมื่อ Exception เกิดขึ้น
  echo "เกิดข้อผิดพลาด: " . $e->getMessage();
}

ในตัวอย่างข้างต้น, Try Block พยายามทำการหาร 10 ด้วย 0 ซึ่งจะทำให้เกิด DivisionByZeroError (ซึ่งเป็นคลาสย่อยของ Exception) เมื่อเกิด Exception, PHP จะข้ามโค้ดที่เหลือใน Try Block และไปยัง Catch Block ที่ตรงกับประเภทของ Exception ที่เกิดขึ้น (หรือ Catch Block ที่รับ Exception เป็น Parent Class)

ใน Catch Block เราสามารถเข้าถึง Object Exception (ในตัวอย่างคือ $e) ซึ่งมีข้อมูลเกี่ยวกับข้อผิดพลาด เช่น Message ($e->getMessage()) และ Stack Trace ($e->getTraceAsString()) ซึ่ง Stack Trace จะมีประโยชน์อย่างมากในการ Debugging เพื่อหาว่า Exception เกิดขึ้นที่ไหนใน Codebase ของเรา

การ Throw Exceptions

นอกจากการจัดการ Exceptions ที่เกิดขึ้นโดย PHP เองแล้ว เรายังสามารถ Throw Exceptions ได้ด้วยตนเอง เพื่อแจ้งให้ทราบว่าเกิดข้อผิดพลาดใน Code ของเรา

การ Throw Exception ทำได้โดยใช้คำสั่ง throw ตามด้วย Object Exception:

function validateAge($age) {
  if ($age < 0) {
    throw new Exception("อายุต้องไม่น้อยกว่า 0");
  }
  // ... โค้ดอื่นๆ ...
}

try {
  validateAge(-5);
} catch (Exception $e) {
  echo "เกิดข้อผิดพลาด: " . $e->getMessage();
}

ในตัวอย่างนี้, ฟังก์ชัน validateAge จะ Throw Exception หาก $age น้อยกว่า 0 เมื่อ Exception ถูก Throw, PHP จะหยุดการทำงานของฟังก์ชันและมองหา Catch Block ที่เหมาะสม

การจัดการ Exceptions ที่แตกต่างกัน

เราสามารถมี Catch Blocks หลายอันเพื่อจัดการ Exceptions ที่แตกต่างกันได้:

try {
  // โค้ดที่อาจทำให้เกิด Exceptions หลายประเภท
  $file = fopen("nonexistent_file.txt", "r");
  $data = json_decode($jsonString); // สมมติว่า $jsonString ไม่ถูกต้อง
} catch (FileNotFoundException $e) { // สมมติว่ามี FileNotFoundException
  echo "ไม่พบไฟล์: " . $e->getMessage();
} catch (JsonException $e) { // สมมติว่ามี JsonException
  echo "JSON ไม่ถูกต้อง: " . $e->getMessage();
} catch (Exception $e) {
  echo "เกิดข้อผิดพลาดทั่วไป: " . $e->getMessage();
} finally {
  // โค้ดที่จะทำงานเสมอ ไม่ว่าจะเกิด Exception หรือไม่
  if (isset($file)) {
    fclose($file);
  }
}

ในตัวอย่างนี้, เรามี Catch Blocks สามอัน:

  • FileNotFoundException: จัดการ Exception ที่เกิดจากการไม่พบไฟล์
  • JsonException: จัดการ Exception ที่เกิดจาก JSON ที่ไม่ถูกต้อง
  • Exception: จัดการ Exceptions ประเภทอื่นๆ ที่ไม่ได้ระบุไว้ก่อนหน้านี้ (Catch Block นี้ควรอยู่เป็นอันดับสุดท้าย เนื่องจากเป็น Parent Class ของ Exceptions อื่นๆ)

ลำดับความสำคัญของ Catch Blocks: PHP จะตรวจสอบ Catch Blocks ตามลำดับจากบนลงล่าง และจะเลือก Catch Block แรกที่ตรงกับประเภทของ Exception ที่เกิดขึ้น ดังนั้น Catch Blocks ที่เฉพาะเจาะจงกว่า (เช่น FileNotFoundException) ควรอยู่ก่อน Catch Blocks ที่ทั่วไปกว่า (เช่น Exception)

Finally Block

นอกจาก Try และ Catch Blocks แล้ว ยังมี Finally Block ซึ่งเป็นส่วนของโค้ดที่จะทำงานเสมอ ไม่ว่าจะเกิด Exception หรือไม่ก็ตาม Finally Block มักใช้สำหรับ Clean-up Operations เช่น การปิดไฟล์ หรือการ Release Resources:

try {
  $file = fopen("data.txt", "r");
  // ... โค้ดที่อ่านข้อมูลจากไฟล์ ...
} catch (Exception $e) {
  echo "เกิดข้อผิดพลาด: " . $e->getMessage();
} finally {
  if (isset($file)) {
    fclose($file); // ปิดไฟล์เสมอ แม้จะเกิด Exception หรือไม่ก็ตาม
  }
}

ในตัวอย่างนี้, Finally Block จะปิดไฟล์ data.txt เสมอ ไม่ว่าจะเกิด Exception ใน Try Block หรือไม่ก็ตาม ซึ่งเป็นสิ่งสำคัญเพื่อป้องกัน Resource Leaks

แนวปฏิบัติที่ดีในการจัดการ Exceptions

  • Throw Exceptions เมื่อเกิดข้อผิดพลาดที่ไม่สามารถแก้ไขได้ในระดับนั้น: หากฟังก์ชันไม่สามารถดำเนินการต่อได้เนื่องจากข้อมูลไม่ถูกต้อง หรือ Resource ไม่พร้อมใช้งาน, ให้ Throw Exception เพื่อแจ้งให้ผู้เรียกทราบ
  • Catch Exceptions ในระดับที่สามารถจัดการได้: Catch Exception ในระดับที่สามารถแก้ไขปัญหา หรือให้ข้อมูลที่เป็นประโยชน์แก่ผู้ใช้งานได้
  • ใช้ Exceptions ที่มีความหมาย: สร้าง Exceptions ที่มีความหมายเฉพาะเจาะจง เพื่อให้ง่ายต่อการ Debugging และการจัดการ
  • หลีกเลี่ยงการ Catch Exceptions โดยไม่ทำอะไรเลย: การ Catch Exception แล้วปล่อยทิ้งไว้โดยไม่ทำอะไรเลย อาจทำให้ปัญหาซ่อนอยู่และยากต่อการ Debugging
  • Log Exceptions: บันทึก Exceptions ไว้ใน Log เพื่อให้สามารถวิเคราะห์ปัญหาที่เกิดขึ้นใน Production ได้

สรุป

การจัดการ Exceptions เป็นส่วนสำคัญของการเขียน Code ที่แข็งแกร่งและเชื่อถือได้ Try-Catch Blocks ช่วยให้เราสามารถจัดการกับข้อผิดพลาดที่อาจเกิดขึ้นใน Application ของเราได้อย่างสง่างาม และป้องกันไม่ให้ Application หยุดทำงานกลางคัน การ Throw Exceptions ช่วยให้เราสามารถแจ้งให้ทราบว่าเกิดข้อผิดพลาดใน Code ของเรา และการใช้ Finally Block ช่วยให้เราสามารถ Clean-up Resources ได้อย่างสม่ำเสมอ

ในบทต่อไป เราจะเรียนรู้เกี่ยวกับการใช้ Dependency Injection ซึ่งเป็นเทคนิคในการลด Coupling ระหว่าง Classes และทำให้ Code ของเราง่ายต่อการ Testing และ Maintenance

Office.in.th Custom Service

Want to build or adapt a system from this structure?

Office.in.th designs and develops enterprise web applications, API integrations, and public- and private-sector management systems, with long-term support.

See our software development service