본문으로 건너뛰기

เนื้อหาภาษาไทย / 태국어 콘텐츠

시스템 가이드 검수 완료된 콘텐츠

การจัดการ Error: try, catch, finally

บทความนี้แนะนำกลไกการจัดการ Error ใน PHP ด้วย `try`, `catch` และ `finally` ซึ่งช่วยให้โปรแกรมรับมือกับ Exception ที่อาจเกิดขึ้นระหว่างการทำงาน เช่น การหารด้วยศู...

การจัดการ Error: try, catch, finally

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

PHP มีกลไกที่ช่วยให้เราจัดการกับ Error ได้อย่างมีประสิทธิภาพ นั่นคือ try, catch, และ finally ซึ่งเป็นส่วนหนึ่งของ Exception Handling

Exception คืออะไร?

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

try, catch, finally คืออะไร?

  • try: เป็น Block ของโค้ดที่เราคาดว่าจะเกิด Exception ขึ้นได้
  • catch: เป็น Block ของโค้ดที่ทำงานเมื่อ Exception เกิดขึ้นใน try block เราสามารถระบุประเภทของ Exception ที่ต้องการดักจับได้
  • finally: เป็น Block ของโค้ดที่ทำงานเสมอ ไม่ว่า Exception จะเกิดขึ้นหรือไม่ก็ตาม มักใช้เพื่อทำความสะอาดทรัพยากร เช่น ปิดไฟล์ หรือยกเลิกการเชื่อมต่อฐานข้อมูล

การใช้งาน try...catch

โครงสร้างพื้นฐานของการใช้งาน try...catch คือ:

try {
  // โค้ดที่อาจจะเกิด Exception
} catch (ExceptionType $e) {
  // โค้ดที่ใช้จัดการ Exception ที่เกิดขึ้น
}

ตัวอย่างที่ 1: การหารด้วยศูนย์

<?php

function divide($numerator, $denominator) {
  try {
    if ($denominator == 0) {
      throw new Exception("Division by zero."); // สร้าง Exception เอง
    }
    return $numerator / $denominator;
  } catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
    return null; // หรือค่าเริ่มต้นอื่น ๆ ที่เหมาะสม
  }
}

echo divide(10, 2) . "\n"; // Output: 5
echo divide(5, 0) . "\n";  // Output: Error: Division by zero. null
?>

ในตัวอย่างนี้ เราสร้างฟังก์ชัน divide ที่รับตัวเลขสองตัวคือ $numerator และ $denominator ภายใน try block เราตรวจสอบว่า $denominator เป็น 0 หรือไม่ ถ้าเป็น 0 เราจะ throw Exception ใหม่ขึ้นมา (เราสามารถสร้าง Exception เองได้) catch block จะดักจับ Exception ที่เกิดขึ้น และแสดงข้อความ Error ออกมา

ตัวอย่างที่ 2: การเปิดไฟล์

<?php

$filename = "myfile.txt";

try {
  $file = fopen($filename, "r");
  if ($file) {
    while (!feof($file)) {
      echo fgets($file) . "<br>";
    }
    fclose($file);
  } else {
    throw new Exception("Unable to open file: " . $filename);
  }
} catch (Exception $e) {
  echo "Error: " . $e->getMessage();
}

?>

ในตัวอย่างนี้ เราพยายามเปิดไฟล์ชื่อ myfile.txt ถ้าเปิดไฟล์ไม่สำเร็จ (เช่น ไฟล์ไม่มีอยู่จริง) ฟังก์ชัน fopen จะคืนค่า false เราจึง throw Exception ขึ้นมา catch block จะดักจับ Exception และแสดงข้อความ Error

การใช้งาน finally

finally block จะทำงานเสมอ ไม่ว่า Exception จะเกิดขึ้นหรือไม่ก็ตาม มักใช้เพื่อทำความสะอาดทรัพยากร

try {
  // โค้ดที่อาจจะเกิด Exception
} catch (ExceptionType $e) {
  // โค้ดที่ใช้จัดการ Exception
} finally {
  // โค้ดที่ทำงานเสมอ
}

ตัวอย่าง: การปิดไฟล์ใน finally block

<?php

$filename = "myfile.txt";
$file = null; // Initialize $file outside the try block

try {
  $file = fopen($filename, "r");
  if (!$file) {
    throw new Exception("Unable to open file: " . $filename);
  }
  while (!feof($file)) {
    echo fgets($file) . "<br>";
  }
} catch (Exception $e) {
  echo "Error: " . $e->getMessage();
} finally {
  if ($file) {
    fclose($file);
    echo "<br>File closed.";
  }
}

?>

ในตัวอย่างนี้ เรากำหนด $file ให้เป็น null ก่อนที่จะเข้าสู่ try block ใน finally block เราตรวจสอบว่า $file ไม่เป็น null (หมายความว่าไฟล์ถูกเปิดแล้ว) ถ้าเป็นเช่นนั้น เราจะปิดไฟล์ด้วย fclose($file) ไม่ว่า Exception จะเกิดขึ้นหรือไม่ก็ตาม ไฟล์จะถูกปิดเสมอ

การดักจับ Exception หลายประเภท

เราสามารถใช้ catch block หลายอันเพื่อดักจับ Exception หลายประเภทได้

try {
  // โค้ดที่อาจจะเกิด Exception หลายประเภท
} catch (InvalidArgumentException $e) {
  // จัดการ InvalidArgumentException
} catch (RuntimeException $e) {
  // จัดการ RuntimeException
} catch (Exception $e) {
  // จัดการ Exception ประเภทอื่น ๆ (default)
}

ข้อควรระวัง: ลำดับของ catch block มีความสำคัญ Exception จะถูกดักจับโดย catch block อันแรกที่ตรงกับประเภทของ Exception นั้น ดังนั้น catch (Exception $e) ควรอยู่เป็นอันสุดท้ายเสมอ เพราะมันจะดักจับ Exception ทุกประเภท (เนื่องจาก Exception คือ Class แม่ของ Exception ทั้งหมด)

กรณีใช้งานจริง

1. การเชื่อมต่อฐานข้อมูล:

<?php

$host = "localhost";
$username = "root";
$password = "";
$database = "mydatabase";

try {
  $conn = new mysqli($host, $username, $password, $database);

  if ($conn->connect_error) {
    throw new Exception("Connection failed: " . $conn->connect_error);
  }

  // ทำงานกับฐานข้อมูล

} catch (Exception $e) {
  echo "Error: " . $e->getMessage();
} finally {
  if (isset($conn)) {
    $conn->close();
  }
}

?>

2. การเรียก API:

<?php

function fetchDataFromAPI($url) {
  try {
    $response = file_get_contents($url);
    if ($response === false) {
      throw new Exception("Failed to fetch data from API: " . $url);
    }
    return json_decode($response, true);
  } catch (Exception $e) {
    echo "Error: " . $e->getMessage();
    return null;
  }
}

$data = fetchDataFromAPI("https://api.example.com/data");

if ($data) {
  // ประมวลผลข้อมูล
  print_r($data);
}

?>

ข้อผิดพลาดที่พบบ่อย

  • ลืม catch block: ถ้า Exception เกิดขึ้นใน try block แต่ไม่มี catch block ที่เหมาะสม โปรแกรมจะหยุดทำงานและแสดงข้อความ Error
  • ลำดับของ catch block ไม่ถูกต้อง: Exception อาจถูกดักจับโดย catch block ที่ไม่ถูกต้อง ทำให้การจัดการ Error ไม่เป็นไปตามที่คาดหวัง
  • ไม่ทำความสะอาดทรัพยากร: ถ้าไม่ปิดไฟล์ หรือยกเลิกการเชื่อมต่อฐานข้อมูล อาจทำให้เกิดปัญหา memory leak หรือ resource exhaustion
  • ไม่ log error: การ log error ช่วยให้เราสามารถติดตามและแก้ไขปัญหาที่เกิดขึ้นในโปรแกรมได้

สรุป

การใช้ try, catch, และ finally เป็นวิธีที่มีประสิทธิภาพในการจัดการ Error ใน PHP ช่วยให้โปรแกรมของเรามีความเสถียรและทนทานมากยิ่งขึ้น การเข้าใจหลักการทำงานและนำไปประยุกต์ใช้จริง จะช่วยให้เราเขียนโปรแกรมที่มีคุณภาพสูงได้

ในบทเรียนถัดไป เราจะมาเรียนรู้เกี่ยวกับการสร้าง Custom Exception เพื่อให้เราสามารถจัดการ Error ได้อย่างละเอียดและตรงจุดมากยิ่งขึ้น

Office.in.th Custom Service

이 구조를 바탕으로 시스템을 개발하거나 맞춤 변경하고 싶으신가요?

Office.in.th는 엔터프라이즈 웹 애플리케이션, API 연동, 공공/민간 업무 관리 시스템을 설계·개발하며 장기 지원을 제공합니다.

소프트웨어 개발 서비스 보기