ตัวอย่าง PHP Try Catch: บทช่วยสอนการจัดการข้อยกเว้นและข้อผิดพลาด
⚡ สรุปอย่างชาญฉลาด
การจัดการข้อผิดพลาดและข้อยกเว้นใน PHP ช่วยให้แอปพลิเคชันมีความเสถียรและปลอดภัยโดยการจัดการกับสภาวะที่ไม่คาดคิดแทนที่จะแสดงข้อผิดพลาดโดยตรง บทความนี้จะอธิบายความแตกต่างระหว่างข้อผิดพลาดและข้อยกเว้น คำสั่ง die ตัวจัดการข้อผิดพลาดแบบกำหนดเอง ระดับการรายงานข้อผิดพลาด และโมเดลข้อยกเว้น try, throw และ catch พร้อมประเภทข้อยกเว้นหลายประเภท

ข้อยกเว้นคืออะไร?
ข้อผิดพลาดคือผลลัพธ์ของโปรแกรมที่ไม่คาดคิดซึ่งตัวโปรแกรมเองไม่สามารถจัดการได้
ข้อผิดพลาดได้รับการแก้ไขโดยการแก้ไขโปรแกรม ตัวอย่างของข้อผิดพลาดอาจเป็นการวนซ้ำไม่สิ้นสุดที่ไม่เคยหยุดดำเนินการ
ข้อยกเว้น คือ ผลลัพธ์ที่ไม่คาดคิดที่เกิดขึ้นในโปรแกรม ซึ่งโปรแกรมสามารถจัดการได้ด้วยตัวเอง
ตัวอย่างของข้อยกเว้น ได้แก่ การพยายามเปิดไฟล์ที่ไม่มีอยู่จริง
ข้อยกเว้นนี้สามารถจัดการได้โดยการสร้างไฟล์หรือให้ผู้ใช้มีตัวเลือกในการค้นหาไฟล์
เหตุใดจึงต้องจัดการกับข้อยกเว้น?
- โปรดหลีกเลี่ยงผลลัพธ์ที่ไม่คาดคิดบนหน้าเว็บของเรา ซึ่งอาจสร้างความรำคาญหรือความหงุดหงิดให้กับผู้ใช้งานได้
- ปรับปรุงความปลอดภัยของแอปพลิเคชันของเราโดยไม่เปิดเผยข้อมูลที่ผู้ใช้ที่เป็นอันตรายอาจใช้เพื่อโจมตีแอปพลิเคชันของเรา
- ข้อยกเว้นใน PHP ใช้เพื่อเปลี่ยนแปลงการทำงานปกติของโปรแกรมหากเกิดข้อผิดพลาดที่คาดการณ์ได้
การจัดการข้อผิดพลาด PHP
เมื่อเกิดข้อผิดพลาด ขึ้นอยู่กับการตั้งค่าคอนฟิกูเรชันของคุณ PHP แสดงข้อความแสดงข้อผิดพลาดในเว็บเบราว์เซอร์พร้อมข้อมูลเกี่ยวกับข้อผิดพลาดที่เกิดขึ้น
PHP มีวิธีการจัดการข้อผิดพลาดอยู่หลายวิธี เราจะมาดูสามวิธีที่ใช้กันทั่วไป:
- คำสั่งตาย – ฟังก์ชัน die รวมฟังก์ชัน echo และ exit ไว้ในฟังก์ชันเดียว มีประโยชน์มากเมื่อเราต้องการแสดงผลข้อความและหยุดการทำงานของสคริปต์เมื่อเกิดข้อผิดพลาด
- ตัวจัดการข้อผิดพลาดแบบกำหนดเอง – เป็นฟังก์ชันที่ผู้ใช้กำหนดซึ่งจะถูกเรียกเมื่อใดก็ตามที่เกิดข้อผิดพลาด
- รายงานข้อผิดพลาด PHP – ข้อความแสดงข้อผิดพลาดจะขึ้นอยู่กับการตั้งค่าการรายงานข้อผิดพลาดของ PHP วิธีนี้มีประโยชน์มากในสภาพแวดล้อมการพัฒนาเมื่อคุณไม่ทราบสาเหตุของข้อผิดพลาด ข้อมูลที่แสดงสามารถช่วยคุณในการแก้ไขข้อบกพร่องของแอปพลิเคชันได้
ข้อผิดพลาดในการจัดการตัวอย่าง
ต่อไปนี้เราจะมาดูตัวอย่างง่ายๆ เกี่ยวกับขั้นตอนการจัดการข้อผิดพลาดกัน
สมมติว่าเรามีสูตรคำนวณที่อาจหารตัวเลขด้วยศูนย์ เราต้องการจัดการกรณีนี้อย่างเรียบร้อยแทนที่จะปล่อยให้ PHP แสดงข้อผิดพลาดออกมา
รหัสด้านล่างใช้ตัวอย่างข้างต้น
<?php
$denominator = 0;
echo 2 / $denominator;
?>
สมมติว่าคุณได้บันทึกไฟล์ simple_error.php ไว้ในโฟลเดอร์ phptuts แล้ว ให้เปิดไฟล์นั้นขึ้นมา URL http://localhost/phptuts/simple_error.php
คุณจะได้รับผลลัพธ์ดังต่อไปนี้
ดังที่คุณเห็นจากผลลัพธ์ข้างต้น ทำให้แอปพลิเคชันของเราดูไม่เป็นมืออาชีพและอาจสร้างความรำคาญให้กับผู้ใช้ได้
เราจะแก้ไขโค้ดข้างต้นและเขียนตัวจัดการข้อผิดพลาดสำหรับแอปพลิเคชัน
<?php $denominator = 0; if ($denominator != 0) { echo 2 / $denominator; } else { echo "cannot divide by zero (0)"; } ?>
สมมติว่าคุณได้บันทึกโค้ดข้างต้นเป็น error_handling.php แล้ว ให้เปิดไฟล์นั้นขึ้นมา URL http://localhost/phptuts/error_handling.php
หมายเหตุ การแสดงข้อความแบบที่แสดงด้านบนแทนการแสดงข้อความดิบๆ เช่น “ไม่พบไฟล์” ถือเป็นแนวทางปฏิบัติที่ดีด้านความปลอดภัย
เรามาดูตัวอย่างอื่นที่ใช้ตัวจัดการข้อผิดพลาดแบบกำหนดเองกัน
ตัวจัดการข้อผิดพลาดแบบกำหนดเองจะถูกตั้งค่าเป็นฟังก์ชันการจัดการข้อผิดพลาด PHP เริ่มต้น และโดยทั่วไปจะแสดงหมายเลขข้อผิดพลาดและข้อความ
รหัสด้านล่างแสดงให้เห็นถึงการดำเนินการตามตัวอย่างข้างต้น
<?php function my_error_handler($error_no, $error_msg) { echo "Oops, something went wrong:"; echo "Error number: [$error_no]"; echo "Error Description: [$error_msg]"; } set_error_handler("my_error_handler"); echo (5 / 0); ?>
เปิด URL http://localhost/phptuts/custom_error_handler.phpคุณจะได้รับผลลัพธ์ดังต่อไปนี้
ดังที่คุณเห็นจากตัวอย่างข้างต้น ตัวจัดการข้อผิดพลาดแบบกำหนดเองมีประสิทธิภาพในแง่ที่ว่า:
- ช่วยให้เราปรับแต่งข้อความแสดงข้อผิดพลาดได้
- ตัวจัดการข้อผิดพลาดแบบกำหนดเองยังสามารถรวมถึงการบันทึกข้อผิดพลาดลงในไฟล์หรือฐานข้อมูล การส่งอีเมลไปยังผู้พัฒนา และการดำเนินการอื่นๆ ที่คล้ายคลึงกันได้อีกด้วย
ต่อไปนี้เราจะมาดูการจัดการข้อผิดพลาดประเภทที่สามกัน เราจะใช้ฟังก์ชัน error_reporting ที่มีอยู่ใน PHP ซึ่งมีไวยากรณ์พื้นฐานดังต่อไปนี้
<?php error_reporting($reporting_level); ?>
ที่นี่
- “error_reporting” เป็นฟังก์ชันการรายงานข้อผิดพลาดของ PHP
- “$reporting_level” เป็นตัวเลือกเสริม และสามารถใช้เพื่อกำหนดระดับการรายงาน หากไม่ได้ระบุระดับการรายงานไว้ PHP จะใช้ระดับการรายงานข้อผิดพลาดเริ่มต้นตามที่ระบุไว้ในไฟล์ php.ini
| ระดับการรายงาน | Descriptไอออน | ตัวอย่าง |
|---|---|---|
| E_คำเตือน | แสดงข้อความเตือนเท่านั้น ไม่หยุดการทำงานของสคริปต์ | error_reporting(E_WARNING); |
| E_ข้อสังเกต | แสดงการแจ้งเตือนที่อาจเกิดขึ้นระหว่างการทำงานของโปรแกรมตามปกติหรืออาจเป็นข้อผิดพลาด | การรายงานข้อผิดพลาด (E_NOTICE); |
| E_USER_ERROR | แสดงข้อผิดพลาดที่ผู้ใช้สร้างขึ้น เช่น ตัวจัดการข้อผิดพลาดแบบกำหนดเอง | การรายงานข้อผิดพลาด (E_USER_ERROR); |
| E_USER_WARNING | แสดงข้อความเตือนที่ผู้ใช้สร้างขึ้น | error_reporting(E_USER_WARNING); |
| E_USER_ประกาศ | แสดงประกาศที่ผู้ใช้สร้างขึ้น | error_reporting(E_USER_NOTICE); |
| E_RECOVERABLE_ERROR | แสดงข้อผิดพลาดที่ไม่ร้ายแรงและสามารถจัดการได้โดยใช้ตัวจัดการข้อผิดพลาดแบบกำหนดเอง | error_reporting(E_RECOVERABLE_ERROR); |
| อี_ออล | แสดงข้อผิดพลาดและคำเตือนทั้งหมด | การรายงานข้อผิดพลาด(E_ALL); |
ความแตกต่างระหว่างข้อผิดพลาดและข้อยกเว้น
- ข้อยกเว้น (Exceptions) เกิดขึ้นและมีจุดประสงค์เพื่อให้ระบบดักจับ ในขณะที่ข้อผิดพลาด (Error) โดยทั่วไปแล้วไม่สามารถแก้ไขได้
- การจัดการข้อยกเว้นใช้วิธีการเชิงวัตถุ ซึ่งหมายความว่าเมื่อเกิดข้อยกเว้นขึ้น ระบบจะสร้างอ็อบเจ็กต์ข้อยกเว้นขึ้นมา ซึ่งประกอบด้วยรายละเอียดของข้อยกเว้นนั้น
ตารางด้านล่างแสดงเมธอดของอ็อบเจ็กต์ข้อยกเว้น
| วิธี | Descriptไอออน | ตัวอย่าง |
|---|---|---|
| getMessage () | แสดงข้อความข้อยกเว้น |
<?php
echo $e->getMessage();
?>
|
| ได้รับCode() | แสดงรหัสตัวเลขที่แสดงถึงข้อยกเว้น |
<?php
echo $e->getCode();
?>
|
| รับไฟล์() | แสดงชื่อไฟล์และเส้นทางที่เกิดข้อยกเว้น |
<?php
echo $e->getFile();
?>
|
| รับสาย() | แสดงหมายเลขบรรทัดที่เกิดข้อยกเว้น |
<?php
echo $e->getLine();
?>
|
| ได้รับTracอี() | แสดงอาร์เรย์ของด้านหลังtrace ก่อนข้อยกเว้น |
<?php print_r( $e->getTrace()); ?> |
| รับก่อนหน้า() | แสดงข้อยกเว้นก่อนหน้านี้ก่อนข้อยกเว้นปัจจุบัน |
<?php
echo $e->getPrevious();
?>
|
| ได้รับTraceAsString() | แสดงด้านหลังtrace ของข้อยกเว้นเป็นสตริงแทนที่จะเป็นอาร์เรย์ |
<?php
echo $e->getTraceAsString();
?>
|
| __toString() | แสดงข้อยกเว้นทั้งหมดเป็นสตริง |
<?php
echo $e->__toString();
?>
|
ด้านล่างนี้เป็นรูปแบบพื้นฐานในการโยนข้อยกเว้น
<?php throw new Exception("This is an exception example"); ?>
ที่นี่
- “throw” เป็นคำสำคัญที่ใช้เพื่อทิ้งข้อยกเว้น
- “new Exception(…)” สร้างอ็อบเจ็กต์ข้อยกเว้นและส่งสตริง “This is an exception example” เป็นพารามิเตอร์ข้อความ
โค้ดด้านบนจะแสดงข้อความต่อไปนี้
ต่อไปนี้เราจะมาดูตัวอย่างการใช้งานการจัดการข้อยกเว้นด้วย throw และ catch เราจะปรับเปลี่ยนตัวอย่างข้างต้นโดยเพิ่ม try, throw และ catch เข้าไปด้วย
มีโครงสร้างพื้นฐานดังต่อไปนี้
<?php try { // code goes here that could potentially throw an exception } catch (Exception $e) { // exception handling code goes here } ?>
ที่นี่
- “try{…}” คือบล็อกของโค้ดที่จะดำเนินการซึ่งอาจก่อให้เกิดข้อยกเว้น
- “catch(Exception $e){…}” คือบล็อกของโค้ดที่จับข้อยกเว้นที่ถูกส่งออกมาและกำหนดวัตถุข้อยกเว้นให้กับตัวแปร $e
โค้ดด้านล่างแสดงตัวอย่างการจัดการข้อยกเว้นพื้นฐานโดยใช้ try, throw และ catch โปรแกรมจะจงใจโยนข้อยกเว้นแล้วจึงดักจับมันไว้
<?php try { $var_msg = "This is an exception example"; throw new Exception($var_msg); } catch (Exception $e) { echo "Message: " . $e->getMessage(); echo ""; echo "getCode(): " . $e->getCode(); echo ""; echo "__toString(): " . $e->__toString(); } ?>
เปิด URL http://localhost/phptuts/exception_handling.phpคุณจะได้รับผลลัพธ์ดังต่อไปนี้
นอกจากนี้ ยังสามารถสร้างข้อยกเว้นหลายรายการสำหรับคำสั่ง try ใน PHP ได้ โดยขึ้นอยู่กับประเภทของข้อยกเว้นที่เกิดขึ้น
ดูบทความเกี่ยวกับ MySQLตัวอย่างการใช้งานการเข้าถึงข้อมูล PHP สำหรับการจัดการข้อยกเว้นหลายประเภท
ข้อยกเว้นหลายประการ
การจัดการข้อยกเว้นหลายรายการจะใช้บล็อก catch หลายบล็อกเพื่อจัดการกับข้อยกเว้นที่เกิดขึ้น การจัดการข้อยกเว้นหลายรายการมีประโยชน์ในกรณีต่อไปนี้:
- คุณต้องการแสดงข้อความที่กำหนดเองโดยขึ้นอยู่กับข้อยกเว้นที่เกิดขึ้น
- คุณต้องการดำเนินการที่ไม่ซ้ำกันขึ้นอยู่กับข้อยกเว้นที่ถูกโยน
ผังงานด้านล่างนี้แสดงให้เห็นถึงวิธีการทำงานของข้อยกเว้นหลายรายการ
เรามาดูตัวอย่างที่ใช้ข้อยกเว้นหลายรายการกัน เราจะแก้ไขโค้ดที่หารตัวเลขด้วยตัวหารที่ส่งเข้ามา
เราคาดว่าจะมีข้อยกเว้นเกิดขึ้นสองประเภท:
- การหารด้วยศูนย์
- หารด้วยจำนวนลบ
เพื่อความง่าย เราจะแสดงเฉพาะประเภทของข้อยกเว้นในบล็อก catch เท่านั้น คลาส Exception ที่มีอยู่ใน PHP ใช้สำหรับโยนข้อยกเว้น เราจะสร้างสองคลาสที่สืบทอดมาจากคลาส Exception และใช้คลาสเหล่านั้นในการโยนข้อยกเว้น
รหัสด้านล่างแสดงการใช้งาน
<?php class DivideByZeroException extends Exception {}; class DivideByNegativeException extends Exception {}; function process($denominator) { try { if ($denominator == 0) { throw new DivideByZeroException(); } else if ($denominator < 0) { throw new DivideByNegativeException(); } else { echo 25 / $denominator; } } catch (DivideByZeroException $ex) { echo "DIVIDE BY ZERO EXCEPTION!"; } catch (DivideByNegativeException $ex) { echo "DIVIDE BY NEGATIVE NUMBER EXCEPTION!"; } catch (Exception $x) { echo "UNKNOWN EXCEPTION!"; } } process(0); ?>
การทดสอบรหัส
เราจะถือว่าคุณได้บันทึกไฟล์ multiple_exceptions.php ไว้ในโฟลเดอร์ phptuts แล้ว
เรียกดูไฟล์ URL http://localhost/phptuts/multiple_exceptions.php
สลับกลับไปที่ไฟล์ PHP และส่ง -1 เป็นพารามิเตอร์ตามที่แสดงในแผนภาพต่อไปนี้
เรียกดูไฟล์ URL http://localhost/phptuts/multiple_exceptions.phpคุณได้ผลลัพธ์อะไรบ้าง? ทีนี้ลองใส่ค่า 3 เป็นพารามิเตอร์ดู คุณได้ผลลัพธ์อะไรบ้าง?
สุดท้ายนี้ บล็อกและโมเดลข้อผิดพลาด PHP 7
PHP เวอร์ชันใหม่เพิ่มส่วนสำคัญสองส่วนเข้าไปในโมเดลข้างต้น บล็อก finally จะทำงานหลังจาก try และ catch ไม่ว่าจะมีข้อยกเว้นเกิดขึ้นหรือไม่ก็ตาม ซึ่งทำให้เหมาะสำหรับการจัดการข้อผิดพลาด เช่น การปิดไฟล์หรือการเชื่อมต่อฐานข้อมูล
ตั้งแต่ PHP 7 เป็นต้นมา ข้อผิดพลาดร้ายแรงหลายอย่างในอดีตจะถูกโยนออกมาในรูปแบบของอ็อบเจ็กต์ Error ทั้ง Exception และ Error ต่างก็ใช้งานอินเทอร์เฟซ Throwable ดังนั้นบล็อก catch (\Throwable $e) จึงสามารถจัดการได้ทั้งสองกรณี
<?php try { $result = 10 / 0; } catch (DivisionByZeroError $e) { echo "Caught: " . $e->getMessage(); } finally { echo "This message always runs"; } ?>
ใน PHP 8 การหารด้วยศูนย์จะทำให้เกิดข้อผิดพลาด DivisionByZeroError บล็อก catch จะรายงานข้อผิดพลาด และบล็อก finally จะทำงานเสมอ โดยจะพิมพ์ข้อความออกมาไม่ว่าจะมีข้อผิดพลาดเกิดขึ้นหรือไม่ก็ตาม








