ใน Module นี้ เราจะมาเรียนรู้เกี่ยวกับการจัดการข้อผิดพลาด (Error Handling) และการจัดการ Exception (Exception Handling) ใน PHP ซึ่งเป็นสิ่งสำคัญอย่างยิ่งในการสร้างแอปพลิเคชันที่มีความเสถียร สามารถรับมือกับสถานการณ์ที่ไม่คาดฝัน และให้ข้อมูลที่เป็นประโยชน์แก่ผู้ใช้หรือผู้พัฒนาเมื่อเกิดปัญหา
ประเภทของข้อผิดพลาดใน PHP (Types of Errors in PHP)
PHP มีระดับของข้อผิดพลาดหลายประเภท ซึ่งแต่ละประเภทมีความรุนแรงและลักษณะการทำงานที่แตกต่างกัน:
- Notice: ข้อผิดพลาดที่ไม่ร้ายแรง มักเกิดจากการเข้าถึงตัวแปรที่ยังไม่ได้กำหนดค่า
- Warning: ข้อผิดพลาดที่ไม่ร้ายแรง แต่ควรได้รับการแก้ไข เช่น การ include ไฟล์ที่ไม่พบ
- Fatal Error: ข้อผิดพลาดร้ายแรงที่ทำให้สคริปต์หยุดการทำงานทันที เช่น การเรียกใช้ฟังก์ชันที่ไม่มีอยู่ หรือการพยายามสร้าง Object จากคลาสที่ไม่มีอยู่
การตั้งค่าการรายงานข้อผิดพลาด (Error Reporting)
คุณสามารถกำหนดระดับการรายงานข้อผิดพลาดใน PHP ได้โดยใช้ฟังก์ชัน error_reporting()
และการตั้งค่าในไฟล์ php.ini
<?php
// รายงานทุกข้อผิดพลาด ยกเว้น Notices
error_reporting(E_ALL & ~E_NOTICE);
// รายงานเฉพาะ Warnings และ Fatal Errors
error_reporting(E_WARNING | E_ERROR);
// รายงานทุกข้อผิดพลาด
error_reporting(E_ALL);
// ไม่รายงานข้อผิดพลาดใดๆ (สำหรับการใช้งานจริง ไม่แนะนำ)
error_reporting(0);
?>
สำหรับการพัฒนา ควรตั้งค่าให้รายงานข้อผิดพลาดทั้งหมด เพื่อช่วยในการตรวจหาและแก้ไขปัญหา แต่สำหรับการใช้งานจริง อาจต้องการปิดการแสดงผลข้อผิดพลาดบนหน้าเว็บเพื่อความปลอดภัยและความเป็นมิตรต่อผู้ใช้
การจัดการข้อผิดพลาดแบบกำหนดเอง (Custom Error Handling)
คุณสามารถกำหนดฟังก์ชันที่จะถูกเรียกใช้เมื่อเกิดข้อผิดพลาดใน PHP ได้โดยใช้ฟังก์ชัน set_error_handler()
<?php
function customErrorHandler($errno, $errstr, $errfile, $errline) {
echo "<b>Error:</b> [$errno] $errstr in $errfile on line $errline<br>";
echo "Ending Script";
die();
}
// ตั้งค่า Error Handler ของเรา
set_error_handler("customErrorHandler");
// ทำให้เกิดข้อผิดพลาด (Warning)
echo $undefined_variable;
// ทำให้เกิดข้อผิดพลาด (Fatal Error) - จะไม่ถูกจับโดย Error Handler ปกติ
// nonExistentFunction();
echo "This line will not be executed if a non-fatal error occurs.";
?>
ข้อควรทราบ: Error Handler ที่กำหนดเองจะไม่สามารถจัดการกับ Fatal Errors ได้
Exception Handling
Exception Handling เป็นกลไกที่มีประสิทธิภาพในการจัดการกับสถานการณ์ที่ไม่คาดฝันที่อาจเกิดขึ้นระหว่างการทำงานของโปรแกรม โดยใช้ Keywords try
, catch
, และ finally
try
บล็อก try
ล้อมรอบโค้ดที่อาจทำให้เกิด Exception
catch
บล็อก catch
ระบุโค้ดที่จะถูกดำเนินการเมื่อ Exception ที่ระบุถูกโยนออกมาจากบล็อก try
คุณสามารถมีหลายบล็อก catch
เพื่อจัดการกับ Exception ประเภทต่างๆ กันได้
finally
บล็อก finally
(ถ้ามี) จะถูกดำเนินการเสมอ ไม่ว่าจะมี Exception เกิดขึ้นหรือไม่ก็ตาม มักใช้สำหรับการทำความสะอาดทรัพยากร (เช่น ปิดไฟล์, ปิด Connection ฐานข้อมูล)
<?php
function divide($dividend, $divisor) {
if ($divisor == 0) {
throw new Exception("Division by zero.");
}
return $dividend / $divisor;
}
try {
echo divide(10, 2) . "<br>";
echo divide(5, 0) . "<br>"; // จะโยน Exception
echo "This line will not be executed.";
} catch (Exception $e) {
echo "Caught exception: " . $e->getMessage() . "<br>";
} finally {
echo "Finally block executed.";
}
echo "Program continues after try-catch block.";
?>
การสร้าง Exception แบบกำหนดเอง (Custom Exceptions)
คุณสามารถสร้างคลาส Exception ของคุณเองได้โดยการสืบทอดจากคลาส Exception
หรือคลาส Exception อื่นๆ ที่มีอยู่ การทำเช่นนี้ช่วยให้คุณสามารถจัดการกับ Exception ที่มีความหมายเฉพาะเจาะจงกับแอปพลิเคชันของคุณได้
<?php
class DivideByZeroException extends Exception {
public function errorMessage() {
// สร้าง Error message ที่กำหนดเอง
return $this->getMessage() . " Please use a non-zero divisor.";
}
}
function divideCustom($dividend, $divisor) {
if ($divisor == 0) {
throw new DivideByZeroException("Cannot divide by zero.");
}
return $dividend / $divisor;
}
try {
echo divideCustom(10, 2) . "<br>";
echo divideCustom(5, 0) . "<br>";
} catch (DivideByZeroException $e) {
echo "Caught custom exception: " . $e->errorMessage() . "<br>";
} catch (Exception $e) {
echo "Caught generic exception: " . $e->getMessage() . "<br>";
}
?>
การโยน Exception อีกครั้ง (Re-throwing Exceptions)
ในบางครั้ง คุณอาจต้องการจับ Exception เพื่อทำการ Logging หรือการจัดการเบื้องต้น แล้วโยน Exception นั้นอีกครั้งเพื่อให้ส่วนอื่นของโค้ดจัดการต่อไป
<?php
function processFile($filename) {
try {
$file = fopen($filename, "r");
if (!$file) {
throw new Exception("Could not open file: " . $filename);
}
// ... ทำงานกับไฟล์ ...
fclose($file);
} catch (Exception $e) {
error_log("Error processing file " . $filename . ": " . $e->getMessage());
throw $e; // โยน Exception อีกครั้ง
}
}
try {
processFile("nonexistent_file.txt");
} catch (Exception $e) {
echo "Caught outer exception: " . $e->getMessage() . "<br>";
}
?>
กิจกรรมใน Module 13
- ทดลองตั้งค่าระดับการรายงานข้อผิดพลาดต่างๆ ใน PHP
- สร้างฟังก์ชัน Error Handler แบบกำหนดเองและทดลองทำให้เกิดข้อผิดพลาดประเภท Notice และ Warning
- เขียนโค้ดที่ใช้บล็อก
try
และcatch
เพื่อจัดการกับ Exception ที่อาจเกิดขึ้น (เช่น การหารด้วยศูนย์) - สร้างคลาส Exception แบบกำหนดเองสำหรับสถานการณ์เฉพาะในโปรแกรมของคุณ
- ทดลองใช้บล็อก
finally
เพื่อให้แน่ใจว่าโค้ดบางส่วนจะถูกดำเนินการเสมอ - (Optional) ลองโยน Exception อีกครั้งภายในบล็อก
catch
ใน Module ถัดไป เราจะมาเรียนรู้เกี่ยวกับฟังก์ชันและไลบรารีที่สำคัญของ PHP ที่ช่วยในการทำงานต่างๆ ได้อย่างมีประสิทธิภาพมากยิ่งขึ้นครับ!