Exceptions ในภาษา PHP

4 February 2017

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

Exceptions คืออะไร

Exception คือกระบวนการจัดการหรือตอบสนองต่อสิ่งที่เกิดขึ้นในโปรแกรม ซึ่งโดยปกติแล้วมักจะเป็นข้อผิดพลาดที่เกิดขึ้นในระหว่างที่โปรแกรมทำงาน เมื่อเกิดข้อผิดพลาดขึ้นโดยทั่วไปโปรแกรมจะหยุดทำงานในทันที แต่เมื่อเราใช้ Exception มันสามารถกำหนดเป็นข้อยกเว้นให้โปรแกรมสามารถทำงานต่อไปได้ โดยละเว้นข้อผิดพลาดนั้นไป และทำการจัดการกับข้อผิดพลาดนั้นด้วยวิธีอื่นต่อไป ในภาษา PHP มีคลาส Exception สำหรับจัดการเกี่ยวกับ Exception พื้นฐานที่ให้คุณสามารถสร้างและควบคุม Exception ได้

try {
    // things to do
} catch (Exception $e) {
    // handing error
}

ในตัวอย่าง เป็นรูปแบบของการจัดการ Exception ในภาษา PHP ในบล็อคของคำสั่ง try นั้นเป็นส่วนการทำงานของโปรแกรมที่อาจจะเกิด Exception ขึ้น เมื่อเกิด Exception โปรแกรมจะทำการ throw Exception ไปยังบล็อคของคำสั่ง catch สำหรับจัดการกับข้อผิดพลาดที่เกิดขึ้น หรือคุณสามารถทำการ throw Exception แบบกำหนดเองได้โดยการใช้คำสั่ง throw

Exception handing

ต่อไปมาดูตัวอย่างการจัดการกับ Exception ในภาษา PHP ซึ่งเป็นโปรแกรมในการหารตัวเลข ซึ่งในการหารตัวเลขนั้นในการเขียนโปรแกรมนั้นจะทำไม่ได้เมื่อตัวหารเป็นศูนย์

<?php

$a = 10;
$b = 0;

try {
    if ($b == 0) {
        throw new Exception("Division by zero.");
    }
    $c = $a / $b;
} catch (Exception $e) {
    echo $e->getMessage();
}

?>

ในตัวอย่าง เป็นการจัดการกับข้อผิดพลาดที่เกิดขึ้นจากการหารตัวเลขในกรณีที่ตัวหารเป็น 0 ในบล็อคของคำสั่ง try เราได้ทำการตรวจสอบค่าของตัวแปร $b ถ้าหากเป็น 0 เราจะทำการ throw Exception ไปยังบล็อคของคำสั่ง catch

throw new Exception("Division by zero.");

นี่เป็นคำสั่งในการ throw ในภาษา PHP เราได้สร้าง Exception จากคลาส Exception และใส่ข้อความผิดพลาดให้กับคลาสผ่านทาง Constructor

catch (Exception $e) {
    echo $e->getMessage();
}

ในบล็อคของคำสั่ง catch เราต้องทำการตรวจจับ Exception ที่ได้ throw ในตัวอย่างเราได้โยน Exception ที่เราสร้างจากคลาส Exception ดังนั้นเราจึงต้องตรวจจับ Exception จากคลานี้ เมธอด getMessage() ใช้สำหรับรับค่าของข้อความผิดพลาดของ Exception

Division by zero.

นี่เป็นผลลัพธ์การทำงานของโปรแกรม เพราะว่าตัวหารเป็น 0 โปรแกรมจึงโยนข้อผิดพาดไปยังบล็อคของคำสั่ง catch และเราแสดงข้อความข้อผิดพลาดสำหรับการจัดการกับ Exception ดังกล่าว

บล็อคคำสั่ง Finally

นอกจากคำสั่ง try และ catch ซึ่งเป็นคำสั่งในการจัดการกับ Exception แล้ว ยังมีคำสั่ง finally ซึ่งเป็นบล็อคคำสั่งที่จะทำงานเสมอ ไม่ว่าโปรแกรมจะเกิด Exception หรือไม่ มันมักจะใช้กับการปิดการทำงานกับไฟล์ IO หรือการเชื่อมต่อกับฐานข้อมูล มาดูตัวอย่างการใช้งานคำสั่ง finally ในภาษา PHP

<?php
$number = 5;

try {

    if (!is_numeric($number)) {
        throw new Exception("Not number exception");
    }

    echo "Number is $number\n";

} catch (Exception $e) {
    echo "Caught: " . $e->getMessage() . "\n";
} finally {
    echo "Finally block";
}

?>

ในตัวอย่าง เป็นโปรแกรมในการตรวจสอบถ้าหากค่าของตัวแปรนั้นเป็นตัวเลขด้วยฟังก์ชัน is_numeric() และถ้าหากค่าในตัวแปรไม่ได้เป็นตัวเลข โปรแกรมจะทำการ throw Exception ไปยังบล็อคของคำสั่ง catch ไม่ว่าในบล็อคของคำสั่ง catch จะทำงานหรือไม่ก็ตาม ในบล็อคของคำสั่ง finally นั้นจะทำงานเสมอ

Number is 5
Finally block
Caught: Not number exception
Finally block

นี่เป็นผลลัพธ์การทำงานของโปรแกรมเมื่อเรารันโปรแกรมสองครั้ง ในครั้งที่สองเราเปลี่ยนค่าในตัวแปรเป็น $number = "marcuscode.com" และคุณจะเห็นว่าโปรแกรมทำงานจะทำงานในบล็อคของคำสั่ง finally เสมอ

การสร้าง Exception แบบกำหนดเอง

ในภาษา PHP คุณสามารถสร้างคลาส Exception ของคุณเองได้ โดยคลาสที่สร้างนั้นจะต้องสืบทอดจากคลาส Exception ซึ่งเป็นคลาสในการจัดการ Exception พื้นฐานในภาษา PHP เมื่อคุณสร้างคลาส Exception ของคุณเอง คุณสามารถกำหนดตัวแปรและเมธอดเพิ่มเติมสำหรับคลาสได้ ต่อไปเป็นตัวอย่างการสร้าง Exception ซึ่งเราจะสร้าง Exception สำหรับตรวจสอบการร้องขอหน้าเว็บของ marcuscode

<?php

// marcuscode.com/user
$request_uri = "/user";

try {

    if (!isUrlExist($request_uri)) {
        throw new MarcuscodeException("Page not found.", 
        $request_uri);
    }

    echo "Welcome!\n";

} catch (MarcuscodeException $e) {

    echo "Caught exception: " . $e->getMessage() . "\n";
    $e->info();

}

function isUrlExist($url) {
    $urls = ["/", "/about", "/tutorials"];
    return in_array($url, $urls);
}

class MarcuscodeException extends Exception {

    public $domain = "http://marcuscode.com";
    public $path;

    public function __construct($message, $path) {
        $this->message = $message;
        $this->path = $path;
    }

    public function info() {
        echo "$this->domain/$this->path" . 
        " doesn't exist on marcuscode.\n";
    }

}

?>

ในตัวอย่าง เราได้สร้างคลาส MarcuscodeException สำหรับจัดการกับ HTTP request สำหรับเว็บไซต์ โดยโปรแกรมจะทำการตรวจสอบถ้าหาก URL ที่ร้องขอนั้นมีอยู่ และจะ throw Exception ขึ้นถ้าหาก URL นั้นไม่พบซึ่งเรามีเมธอด isUrlExist() สำหรับตรวจสอบ URL ว่ามีอยู่หรือไม่

class MarcuscodeException extends Exception {

    public $domain = "http://marcuscode.com";
    public $path;

    public function __construct($message, $path) {
        $this->message = $message;
        $this->path = $path;
    }

    public function info() {
        echo "$this->domain/$this->path" . 
        " doesn't exist on marcuscode.\n";
    }

}

นี่เป็นคลาสที่เราสร้างขึ้น MarcuscodeException และสืบทอดจากคลาส Exception เราได้สร้างตัวแปรและเมธอด info() สำหรับแสดงข้อมูลเพิ่มสำหรับข้อผิดพลาดเมื่อไม่พบ URL ที่ร้องขอ หลังจากที่สืบทอดจากคลาส Exception แล้ว เราไม่สามารถทำการ Override เมธอดจากคลาสหลักได้เพราะว่าเมธอดเหล่านั้นเป็น final เมธอด

Caught exception: Page not found.
http://marcuscode.com//user doesn't exist on marcuscode.
Welcome!

นี่เป็นผลลัพธ์การทำงานของโปรแกรม อันแรกคือเมื่อผู้ใช้ร้องขอ URL /user โปรแกรมจะแสดงข้อผิดพลาดว่าไม่พบหน้าเว็บ และในผลลัพธ์ที่สองเมื่อเราลองเข้าถึง URL ที่มีอยู่โดยการเปลี่ยนค่าในตัวแปร $request_uri เป็น /about จะได้รับข้อความยินดีต้อนรับเข้าสู่เว็บไซต์

คลาส Exception

ในการทำงานกับ Exception ในภาษา PHP นั้นเราจะใช้งานคลาส Exception เป็นหลัก และในภาษา PHP ยังมีคลาสในการจัดการเกี่ยวกับ Exception เป็นจำนวนมากที่สร้างและสืบทอดจากคลาสนี้ สำหรับโครงสร้างของคลาส Exception นั้นจะประกอบไปด้วยตัวแปรและเมธอดต่อไปนี้

MembersDescription
codeรหัสของข้อผิดพลาด
fileไฟล์ของข้อผิดพลาด
lineบรรทัดที่เกิดข้อผิดพลาด
messageข้อความผิดพลาด
getCode()รับค่าบรรทัดที่เกิดข้อผิดพลาด
getFile()รับค่าไฟล์ที่เกิดข้อผิดพลาดขึ้น
getLine()รับค่าบรรทัดที่เกิดข้อผิดพลาดขึ้น
getMessage()รับค่าข้อความของข้อผิดพลาด
getTrace()รับรายละเอียดในการตรวจจับข้อผิดพลาด
getTraceAsString()รับรายละเอียดในการตรวจจับข้อผิดพลาดเป็น String

ตัวแปรทั้งหมดในคลาสนั้นเป็นแบบ private คุณสามารถกำหนดค่าให้กับตัวแปรเหล่านี้ได้ภายใน Constructor และเมธอดของคลาสนั้นไม่สามารถทำการ Override ได้เมื่อคุณทำการสืบทอดคลาส

ในภาษา PHP นั้นมี Predefined Exceptions เป็นจำนวนมากสำหรับจัดการกับข้อผิดพลาดพื้นฐาน ซึ่งคุณสามารถเรียนรู้เพิ่มเติมได้ที่นี่ http://php.net/manual/en/reserved.exceptions.php

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

บทความนี้เป็นประโยชน์หรือไม่? Yes · No