ตัวอย่าง PHP Try Catch: บทช่วยสอนการจัดการข้อยกเว้นและข้อผิดพลาด

⚡ สรุปอย่างชาญฉลาด

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

  • ⚠️ ข้อผิดพลาด vs ข้อยกเว้น: โดยทั่วไปแล้ว ข้อผิดพลาดจะไม่สามารถแก้ไขได้ ในขณะที่ข้อยกเว้นเป็นผลลัพธ์ที่ไม่คาดคิดซึ่งโปรแกรมสามารถตรวจจับและจัดการได้
  • 🛡️ เหตุผลที่ควรจัดการ: การจัดการข้อผิดพลาดช่วยป้องกันผลลัพธ์ที่ไม่พึงประสงค์ ปกป้องผู้ใช้ และหลีกเลี่ยงการรั่วไหลของรายละเอียดที่ผู้โจมตีอาจนำไปใช้ประโยชน์ได้
  • 🛑 ข้อความจากแม่พิมพ์: ฟังก์ชัน `die` จะพิมพ์ข้อความและหยุดการทำงานของสคริปต์ ซึ่งเป็นวิธีที่รวดเร็วในการหยุดการทำงานเมื่อเกิดข้อผิดพลาด
  • 🛠️ ตัวจัดการแบบกำหนดเอง: set_error_handler() จะส่งต่อข้อผิดพลาดไปยังฟังก์ชันของคุณเอง เพื่อให้คุณสามารถบันทึก ส่งอีเมล หรือจัดรูปแบบข้อความได้ตามต้องการ
  • 📢 การรายงานข้อผิดพลาด: ฟังก์ชัน error_reporting() และระดับต่างๆ เช่น E_ALL จะควบคุมว่า PHP จะแสดงคำเตือนและข้อความแจ้งเตือนใดบ้าง ซึ่งมีประโยชน์ในระหว่างการพัฒนา
  • 🧲 ลอง โยน รับ: บล็อก try จะรันโค้ดที่มีความเสี่ยง บล็อก throw จะทำให้เกิดข้อยกเว้น และบล็อก catch จะจัดการกับข้อยกเว้นนั้นโดยใช้วิธีการของอ็อบเจ็กต์ข้อยกเว้น
  • 🤖 AI ช่วยเหลือ: เครื่องมือ AI สามารถเพิ่มการจัดการ try-catch ให้กับโค้ดที่มีอยู่ และอธิบายโครงสร้างสแต็กที่ซับซ้อนได้ tracหรือข้อความแสดงข้อผิดพลาด

การจัดการข้อผิดพลาดและข้อยกเว้นใน PHP

ข้อยกเว้นคืออะไร?

ข้อผิดพลาดคือผลลัพธ์ของโปรแกรมที่ไม่คาดคิดซึ่งตัวโปรแกรมเองไม่สามารถจัดการได้

ข้อผิดพลาดได้รับการแก้ไขโดยการแก้ไขโปรแกรม ตัวอย่างของข้อผิดพลาดอาจเป็นการวนซ้ำไม่สิ้นสุดที่ไม่เคยหยุดดำเนินการ

ข้อยกเว้น คือ ผลลัพธ์ที่ไม่คาดคิดที่เกิดขึ้นในโปรแกรม ซึ่งโปรแกรมสามารถจัดการได้ด้วยตัวเอง

ตัวอย่างของข้อยกเว้น ได้แก่ การพยายามเปิดไฟล์ที่ไม่มีอยู่จริง

ข้อยกเว้นนี้สามารถจัดการได้โดยการสร้างไฟล์หรือให้ผู้ใช้มีตัวเลือกในการค้นหาไฟล์

เหตุใดจึงต้องจัดการกับข้อยกเว้น?

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

การจัดการข้อผิดพลาด PHP

เมื่อเกิดข้อผิดพลาด ขึ้นอยู่กับการตั้งค่าคอนฟิกูเรชันของคุณ PHP แสดงข้อความแสดงข้อผิดพลาดในเว็บเบราว์เซอร์พร้อมข้อมูลเกี่ยวกับข้อผิดพลาดที่เกิดขึ้น

PHP มีวิธีการจัดการข้อผิดพลาดอยู่หลายวิธี เราจะมาดูสามวิธีที่ใช้กันทั่วไป:

  1. คำสั่งตาย – ฟังก์ชัน die รวมฟังก์ชัน echo และ exit ไว้ในฟังก์ชันเดียว มีประโยชน์มากเมื่อเราต้องการแสดงผลข้อความและหยุดการทำงานของสคริปต์เมื่อเกิดข้อผิดพลาด
  2. ตัวจัดการข้อผิดพลาดแบบกำหนดเอง – เป็นฟังก์ชันที่ผู้ใช้กำหนดซึ่งจะถูกเรียกเมื่อใดก็ตามที่เกิดข้อผิดพลาด
  3. รายงานข้อผิดพลาด PHP – ข้อความแสดงข้อผิดพลาดจะขึ้นอยู่กับการตั้งค่าการรายงานข้อผิดพลาดของ PHP วิธีนี้มีประโยชน์มากในสภาพแวดล้อมการพัฒนาเมื่อคุณไม่ทราบสาเหตุของข้อผิดพลาด ข้อมูลที่แสดงสามารถช่วยคุณในการแก้ไขข้อบกพร่องของแอปพลิเคชันได้

ข้อผิดพลาดในการจัดการตัวอย่าง

ต่อไปนี้เราจะมาดูตัวอย่างง่ายๆ เกี่ยวกับขั้นตอนการจัดการข้อผิดพลาดกัน

สมมติว่าเรามีสูตรคำนวณที่อาจหารตัวเลขด้วยศูนย์ เราต้องการจัดการกรณีนี้อย่างเรียบร้อยแทนที่จะปล่อยให้ PHP แสดงข้อผิดพลาดออกมา

รหัสด้านล่างใช้ตัวอย่างข้างต้น

<?php
$denominator = 0;
echo 2 / $denominator;
?>

สมมติว่าคุณได้บันทึกไฟล์ simple_error.php ไว้ในโฟลเดอร์ phptuts แล้ว ให้เปิดไฟล์นั้นขึ้นมา URL http://localhost/phptuts/simple_error.php

คุณจะได้รับผลลัพธ์ดังต่อไปนี้

การจัดการข้อผิดพลาด 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

หมายเหตุ การแสดงข้อความแบบที่แสดงด้านบนแทนการแสดงข้อความดิบๆ เช่น “ไม่พบไฟล์” ถือเป็นแนวทางปฏิบัติที่ดีด้านความปลอดภัย

เรามาดูตัวอย่างอื่นที่ใช้ตัวจัดการข้อผิดพลาดแบบกำหนดเองกัน

ตัวจัดการข้อผิดพลาดแบบกำหนดเองจะถูกตั้งค่าเป็นฟังก์ชันการจัดการข้อผิดพลาด 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คุณจะได้รับผลลัพธ์ดังต่อไปนี้

การจัดการข้อผิดพลาด 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” เป็นพารามิเตอร์ข้อความ

โค้ดด้านบนจะแสดงข้อความต่อไปนี้

ตัวจัดการข้อยกเว้น PHP ใน PHP

ต่อไปนี้เราจะมาดูตัวอย่างการใช้งานการจัดการข้อยกเว้นด้วย 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คุณจะได้รับผลลัพธ์ดังต่อไปนี้

ตัวจัดการข้อยกเว้น PHP ใน 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 ใน PHP

สลับกลับไปที่ไฟล์ PHP และส่ง -1 เป็นพารามิเตอร์ตามที่แสดงในแผนภาพต่อไปนี้

ตัวจัดการข้อยกเว้น PHP ใน PHP

เรียกดูไฟล์ 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 จะทำงานเสมอ โดยจะพิมพ์ข้อความออกมาไม่ว่าจะมีข้อผิดพลาดเกิดขึ้นหรือไม่ก็ตาม

คำถามที่พบบ่อย

ในการใช้งานจริง ให้ตั้งค่า display_errors เป็น Off และ log_errors เป็น On ในไฟล์ php.ini และกำหนดให้ error_log บันทึกไปยังไฟล์ นอกจากนี้ คุณยังสามารถเรียกใช้ error_log('message') เพื่อบันทึกข้อความที่กำหนดเองโดยไม่เปิดเผยข้อมูลใดๆ ให้กับผู้เข้าชมได้

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

ข้อผิดพลาดที่ไม่ได้รับการจัดการจะกลายเป็นข้อผิดพลาดร้ายแรง หยุดการทำงานของสคริปต์ และแสดงข้อความ "Uncaught Exception" พร้อมกับสแต็ก trace. ตัวจัดการส่วนกลางที่ตั้งค่าด้วย set_exception_handler สามารถดักจับข้อผิดพลาดเหล่านี้ได้ในกรณีสุดท้าย

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

ใช่ค่ะ วางข้อความลงไปได้เลยค่ะ tracและ AI สามารถระบุบรรทัดที่ล้มเหลว ลำดับการเรียกที่นำไปสู่จุดนั้น และสาเหตุที่เป็นไปได้ จากนั้นจึงแนะนำวิธีแก้ไข เช่น การตรวจสอบค่าว่างหรือการแก้ไขอาร์กิวเมนต์

สรุปโพสต์นี้ด้วย: