PHP Go Pro : Exception อย่างมืออาชีพด้วย Observer Pattern
หน้าแรก PHP MySQL เกร็ดความรู้ PHP Go Pro : Exception อย่างมืออาชีพด้วย Observer Pattern
สวัสดีครับ วันนี้ผมจะมาพูดถึงการจัดการ Exception แบบที่มืออาชีพเค้าทำกัน
เคยสงสัยไหมครับว่าเวลาระบบที่ทำงาน 24 ชั่วโมงมัน Error เนี่ย แล้ว Admin เค้ารู้กันได้อย่างไร และ Admin เค้านั่งกันหน้าจอเพื่อเฝ้ามันหรือเปล่า .... ไม่ใช่เลยนะครับ
Admin ก็มีลูกมีเมีย และ Admin ไม่ได้ใช้วิธีเติมน้ำมันหรือเปลี่ยนถ่านในการชาร์จพลัง การแจ้งเตือนต่างๆเหล่านี้อาจจะมาจากหลายๆช่องทางโดยที่ทำจากโค้ดเพียงจุดเดียว
จุดที่เราคุ้นเคยกันดี Exception ครับ แต่วันนี้เราจะมา implement Exception โดยใช้ Design Pattern แบบ Observer
โดยใช้ Interface SPLObject และ SPLObserver ซึ่งมีมากับ PHP ในส่วนของ Simple PHP Libary อยู่แล้วนะครับ โดยหลักการง่ายๆเลย คือ
ถ้าจำกันได้ Observer จะ Monitor Object แล้วมันเกี่ยวกับ Exception ยังไงใช่ไหมครับ อย่างนี้ครับ
ถ้าเรา Implement Exception Handler เป็น SPLObject โดยมี Method 3 method หลักๆคือ
attach() ติดตั้ง Observer เข้ากับ Object
detach() ยกเลิกการเชื่อม Observer เข้ากับ Object
notify() แจ้ง Message ไปยัง Observer ที่ยังเชื่อมต่ออยู่ทั้งหมด
ตัวอย่างการ Implement Exception
<?php
class ExceptionHandler implements SplSubject {
/**
* Private Member แบบอะเรย์สำหรับเก็บ SPLObserver Object เพื่อทำการ Notity เกี่ยวกับ Exception
*
* @var array
*/
private $observers = array();
/**
* Exception ที่ต้องการจะ Handle
*
* @var Exception
*/
public $exception;
/**
* Constructor
*
* @return ExceptionHandler
*/
function __construct() { }
/**
* Method สำหรับทำการ register SPLObject เพื่อเอาไว้ Notify
*
* @param SplObserver
* @return void
*/
public function attach(SplObserver $obs)
{
$id = spl_object_hash($obs);
$this->observers[$id] = $obs;
}
/**
* Method สำหรับ unregister SPLObserver ออกจากรายการที่ต้อง Notify
*
* @param SplObserver The observer to detach
* @return void
*/
public function detach(SplObserver $obs)
{
$id = spl_object_hash($obs);
unset($this->observers[$id]);
}
/**
* Method สำหรับทำการ Notify SPLObject ที่ Register ไว้ทั้งหมด
*
* @return void
*/
public function notify()
{
foreach($this->observers as $obs)
{
$obs->update($this); //เรียกใช้ Interface method ของ SPLObserver
}
}
/**
* Method สำหรับการ register custom exception handler เข้ากับ PHP โดยใช้ set_exception_handler
*
* @return void
*/
public function handle(Exception $e)
{
$this->exception = $e;
$this->notify();
}
}
แล้วทีนี้ เรา Implement Observer หลายๆแบบขึ้นมา เช่น
MailReporter
DBLogger
SyslogNgWriter
อันนี้เป็นตัวอย่าง Observer แบบเกรียนเล็กน้อยนะครับ :lol: สมมติว่ามัน Write Log ลง Database แล้วกันนะครับ
<?php
class DBLogger implements SplObserver
{
public function update(SplSubject $subject)
{
//ทำการบันทึก Log ลง Database บลา บลา บลา
//โดยใช้ Object $subject->exception
echo $subject->exception->getMessage();
echo $subject->exception->getCode();
}
}
โดยทั้งหมดเป็น SPLObserver
แล้วเราทำการ Attache Observer ทั้งหมดเข้ากับ Exception Handler
แล้วเราใช้คำสั่ง set_exception_handler เพื่อโยงการทำงานทั้งหมดเข้าด้วยกัน เช่นตัวอย่างนี้
<?php
require_once('ExceptionHandler.php');
require_once('DBLogger.php');
// Create the ExceptionHandler
$handler = new ExceptionHandler();
// Attach an Exception Logger and Mailer
$handler->attach(new DBLogger());
//$handler->attach(new Mailer());
// Set ExceptionHandler::handle() as the default
set_exception_handler(array($handler, 'handle'));
throw new Exception("Error Message","999");
แล้วสุดท้ายเมื่อมีการใช้คำสั่ง
throw new Exception('ข้อความแจ้งตือน','รหัสข้อผิดพลาด')
การแจ้งเตือนทั้งหมดจะถูกกระทำผ่าน Observer ที่ attached อยู่ด้วยทั้งหมดทันที เป็นไงบ้างครับ ไม่ยากเลยใช่ไหนครับ
สำหรับคนที่รอโค้ดตัวอย่าง รอสักสองสามวันนะครับ เดี๋ยวเอามาเผื่อไว้ให้นะครับ
แต่ถ้าอ่านแล้วลอง Check manual ตามไปด้วยน่าจะเข้าใจได้ และสามารถ Implement ได้เลยนะครับ
ต้องขออภัยด้วยนะครับ ช่วงที่ผ่านมาประสบความวุ่นวายมากมาย จนเกือบเป็นวิกฤติชีวิตไปซะแล้ว
ตอนนี้ เกือบจะกลับมาเป็นปกติแล้ว จะพยายามมาอัพเดทบล็อกกันต่อไปนะครับ
นอกจาก Series PHP Go Pro แล้ว ผมว่าจะเขียนคัมภีร์เถ้าแก่ Software House อีกสัก Series
ซึ่งจะมาแบ่งปันประสบการณ์การจัดตั้งบริษัท Software House สักแห่งกันตั้งแต่ต้นจนได้รับ BOI กันไปเลย 555+
หวังว่าคงจะได้เขียนสักทีนะครับ
Credits:
devzone.zend.com
www.php.net
จาก: http://www.narisa.com/forums/index.php?app=blog&module=display§ion=blog&blogid=26&showentry=2529
ขึ้นไปด้านบน
