การใช้งาน Exception ที่สร้างขึ้นเอง
ในบทที่แล้ว เราได้เรียนรู้วิธีการสร้าง Custom Exception ซึ่งเป็น Exception ที่เรากำหนดเองเพื่อให้สอดคล้องกับความต้องการของโปรเจกต์ของเรา ในบทนี้ เราจะมาดูวิธีการใช้งาน Custom Exception ที่เราสร้างขึ้นมาจริงๆ ว่าเราจะโยน (throw) และจัดการ (catch) มันอย่างไร
Throw CustomException
การโยน Custom Exception ก็เหมือนกับการโยน Exception ทั่วไป คือใช้คำสั่ง throw ตามด้วย Instance ของ Custom Exception ที่เราสร้างขึ้น ตัวอย่างเช่น สมมติว่าเรามี Custom Exception ชื่อ InvalidEmailException ที่เราสร้างขึ้นในบทที่แล้ว:
class InvalidEmailException extends Exception {
public function __construct(string $message = "Invalid email address", int $code = 0, Throwable $previous = null) {
parent::__construct($message, $code, $previous);
}
}
เราสามารถโยน Exception นี้ได้ดังนี้:
function validateEmail(string $email): void {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidEmailException("The email address '{$email}' is not valid.");
}
echo "Email is valid.";
}
// Example usage
try {
validateEmail("invalid-email");
} catch (InvalidEmailException $e) {
echo "Error: " . $e->getMessage();
}
ในตัวอย่างนี้ ฟังก์ชัน validateEmail จะตรวจสอบว่าอีเมลที่ป้อนเข้ามานั้นถูกต้องหรือไม่ ถ้าไม่ถูกต้อง มันจะโยน InvalidEmailException พร้อมกับข้อความแสดงข้อผิดพลาด
Catch CustomException
เมื่อเราโยน Custom Exception แล้ว เราต้องจัดการมันด้วย try-catch block เหมือนกับ Exception ทั่วไป สิ่งที่สำคัญคือเราต้องระบุประเภทของ Exception ที่เราต้องการจับใน catch block:
try {
// Code that might throw an InvalidEmailException
validateEmail("invalid-email");
} catch (InvalidEmailException $e) {
// Handle the InvalidEmailException
echo "Caught InvalidEmailException: " . $e->getMessage();
// You can also log the error, display a user-friendly message, etc.
} catch (Exception $e) {
// Handle other types of Exceptions
echo "Caught a different Exception: " . $e->getMessage();
}
ในตัวอย่างนี้ เรามี try-catch block ที่จะจับ InvalidEmailException ถ้าเกิด Exception นี้ขึ้น มันจะแสดงข้อความแสดงข้อผิดพลาดที่ได้จาก Exception ถ้าเกิด Exception อื่นๆ ขึ้น (ที่ไม่ใช่ InvalidEmailException) มันจะถูกจับโดย catch (Exception $e) ซึ่งเป็น catch block ทั่วไปสำหรับ Exception ทุกประเภท
ข้อควรจำ: ลำดับของ catch block มีความสำคัญ Exception ที่เฉพาะเจาะจงกว่า (เช่น InvalidEmailException) ควรอยู่ก่อน Exception ที่ทั่วไปกว่า (เช่น Exception) มิฉะนั้น Exception ที่เฉพาะเจาะจงกว่าอาจจะไม่ถูกจับเลย
การจัดการ Error เฉพาะ
Custom Exception ช่วยให้เราสามารถจัดการ error ได้อย่างเฉพาะเจาะจงมากขึ้น เพราะเราสามารถเพิ่ม properties และ methods ที่เฉพาะเจาะจงให้กับ Custom Exception ของเราได้ ตัวอย่างเช่น สมมติว่าเราเพิ่ม property $invalidEmail ให้กับ InvalidEmailException:
class InvalidEmailException extends Exception {
private $invalidEmail;
public function __construct(string $email, string $message = "Invalid email address", int $code = 0, Throwable $previous = null) {
parent::__construct($message, $code, $previous);
$this->invalidEmail = $email;
}
public function getInvalidEmail(): string {
return $this->invalidEmail;
}
}
ตอนนี้เราสามารถเข้าถึงอีเมลที่ไม่ถูกต้องได้ใน catch block:
function validateEmail(string $email): void {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidEmailException($email, "The email address '{$email}' is not valid.");
}
echo "Email is valid.";
}
try {
validateEmail("invalid-email");
} catch (InvalidEmailException $e) {
echo "Invalid email: " . $e->getInvalidEmail() . ". Error message: " . $e->getMessage();
// You can use the invalid email to log it, display it to the user, etc.
} catch (Exception $e) {
echo "Caught a different Exception: " . $e->getMessage();
}
ในตัวอย่างนี้ เราสามารถเข้าถึงอีเมลที่ไม่ถูกต้องได้โดยใช้ $e->getInvalidEmail() ซึ่งช่วยให้เราสามารถจัดการกับข้อผิดพลาดได้อย่างละเอียดมากขึ้น
ตัวอย่างการใช้งาน Custom Exception ในสถานการณ์จริง
สมมติว่าเรากำลังสร้างระบบจัดการผู้ใช้ และเราต้องการตรวจสอบว่าชื่อผู้ใช้ (username) ที่ป้อนเข้ามานั้นถูกต้องตามเงื่อนไขหรือไม่ (เช่น ต้องมีความยาวระหว่าง 5 ถึง 20 ตัวอักษร และต้องประกอบด้วยตัวอักษรและตัวเลขเท่านั้น) เราสามารถสร้าง Custom Exception ชื่อ InvalidUsernameException เพื่อจัดการกับกรณีที่ชื่อผู้ใช้ไม่ถูกต้อง:
class InvalidUsernameException extends Exception {
private $username;
public function __construct(string $username, string $message = "Invalid username", int $code = 0, Throwable $previous = null) {
parent::__construct($message, $code, $previous);
$this->username = $username;
}
public function getUsername(): string {
return $this->username;
}
}
จากนั้นเราสามารถสร้างฟังก์ชันเพื่อตรวจสอบชื่อผู้ใช้และโยน InvalidUsernameException ถ้าชื่อผู้ใช้ไม่ถูกต้อง:
function validateUsername(string $username): void {
if (strlen($username) < 5 || strlen($username) > 20) {
throw new InvalidUsernameException($username, "Username must be between 5 and 20 characters.");
}
if (!preg_match("/^[a-zA-Z0-9]+$/", $username)) {
throw new InvalidUsernameException($username, "Username must contain only letters and numbers.");
}
echo "Username is valid.";
}
และสุดท้าย เราสามารถใช้ try-catch block เพื่อจัดการกับ InvalidUsernameException:
try {
validateUsername("inv");
} catch (InvalidUsernameException $e) {
echo "Invalid username: " . $e->getUsername() . ". Error: " . $e->getMessage();
// Log the error, display a user-friendly message, etc.
} catch (Exception $e) {
echo "An unexpected error occurred: " . $e->getMessage();
}
ตัวอย่างนี้แสดงให้เห็นว่า Custom Exception ช่วยให้เราสามารถจัดการกับข้อผิดพลาดได้อย่างเฉพาะเจาะจงและมีประสิทธิภาพมากขึ้น ทำให้โค้ดของเรามีความชัดเจนและง่ายต่อการบำรุงรักษา
สรุป
การใช้งาน Custom Exception เป็นเทคนิคที่มีประโยชน์ในการจัดการข้อผิดพลาดใน PHP ช่วยให้เราสามารถระบุประเภทของข้อผิดพลาดได้อย่างชัดเจน และจัดการกับข้อผิดพลาดแต่ละประเภทได้อย่างเหมาะสม การสร้าง Custom Exception นั้นง่าย เพียงแค่สืบทอดคุณสมบัติจากคลาส Exception และเพิ่ม properties และ methods ที่เฉพาะเจาะจงตามความต้องการของโปรเจกต์ของเรา
ในบทถัดไป เราจะมาเรียนรู้เกี่ยวกับ Logging ซึ่งเป็นอีกหนึ่งเครื่องมือสำคัญในการจัดการข้อผิดพลาดและการตรวจสอบการทำงานของระบบ