ข้อยกเว้นใช้เพื่อเปลี่ยนแปลงโฟลว์ปกติของสคริปต์เมื่อเกิดข้อผิดพลาดที่ระบุ
PHP 5 นำเสนอแนวทางเชิงวัตถุแบบใหม่ในการจัดการข้อผิดพลาด
การจัดการข้อยกเว้นใช้เพื่อเปลี่ยนแปลงโฟลว์ปกติของสคริปต์เมื่อเกิดเงื่อนไขข้อผิดพลาด (ข้อยกเว้น) ที่ระบุ สถานการณ์นี้เรียกว่าข้อยกเว้น
เมื่อมีการทริกเกอร์ข้อยกเว้น มักจะเกิดขึ้น:
สถานะรหัสปัจจุบันจะถูกบันทึก
การดำเนินการโค้ดถูกสลับไปยังฟังก์ชันตัวจัดการข้อยกเว้นที่กำหนดไว้ล่วงหน้า (กำหนดเอง)
ตัวประมวลผลอาจรีสตาร์ทการเรียกใช้โค้ดจากสถานะโค้ดที่บันทึกไว้ ยุติการเรียกใช้สคริปต์ หรือดำเนินการสคริปต์ต่อจากตำแหน่งอื่นในโค้ด ทั้งนี้ขึ้นอยู่กับสถานการณ์
เราจะแสดงวิธีการจัดการข้อผิดพลาดต่างๆ:
การใช้ข้อยกเว้นขั้นพื้นฐาน
สร้างตัวจัดการข้อยกเว้นแบบกำหนดเอง
ข้อยกเว้นหลายประการ
โยนข้อยกเว้นอีกครั้ง
ตั้งค่าตัวจัดการข้อยกเว้นระดับบนสุด
หมายเหตุ: ข้อยกเว้นควรใช้ในสถานการณ์ข้อผิดพลาดเท่านั้น และไม่ควรใช้เพื่อข้ามไปยังตำแหน่งอื่นในโค้ดที่จุดที่ระบุ
เมื่อมีข้อยกเว้นเกิดขึ้น โค้ดต่อไปนี้จะไม่ทำงานต่อไป และ PHP จะพยายามค้นหาบล็อกโค้ด "catch" ที่ตรงกัน
หากตรวจไม่พบข้อยกเว้นและไม่ได้รับการจัดการตามนั้นโดยใช้ set_Exception_handler() จะเกิดข้อผิดพลาดร้ายแรง (ข้อผิดพลาดร้ายแรง) และข้อความแสดงข้อผิดพลาด "Uncaught Exception" จะถูกส่งออก
ลองโยนข้อยกเว้นโดยไม่จับมัน:
<?php // สร้างฟังก์ชันที่มีการจัดการข้อยกเว้น การทำงาน เช็คนัม ( $number ) - ถ้า ( $number > 1 ) - โยน ใหม่ ข้อ ยกเว้น ( " ค่าต้องเป็น 1 หรือต่ำกว่า " ) ; กลับ จริง ; } // ทริกเกอร์ข้อยกเว้น เช็คนั ม ( 2 ) ;
รหัสข้างต้นจะได้รับข้อผิดพลาดคล้ายกับสิ่งนี้:
ข้อผิดพลาดร้ายแรง: ข้อยกเว้นที่ไม่ได้ตรวจสอบ 'ข้อยกเว้น' พร้อมข้อความ 'ค่าต้องเป็น 1 หรือต่ำกว่า' ใน /www/codercto/test/test.php:7 การติดตามสแต็ก: #0 /www/codercto/test/test.php(13): checkNum (2) #1 {main} โยนใน /www/codercto/test/test.php ออนไลน์ 7
เพื่อหลีกเลี่ยงข้อผิดพลาดที่เห็นในตัวอย่างข้างต้น เราจำเป็นต้องสร้างโค้ดที่เหมาะสมเพื่อจัดการกับข้อยกเว้น
รหัสการจัดการข้อยกเว้นที่เหมาะสมควรประกอบด้วย:
ลอง - ฟังก์ชั่นที่ใช้ข้อยกเว้นควรอยู่ภายในบล็อก "ลอง" หากไม่มีข้อยกเว้นเกิดขึ้น โค้ดจะยังคงดำเนินการตามปกติ แต่หากมีการทริกเกอร์ข้อยกเว้น ข้อยกเว้นก็จะถูกส่งออกไป
Throw - ระบุวิธีการทริกเกอร์ข้อยกเว้น การ "โยน" แต่ละครั้งจะต้องสอดคล้องกับ "การจับ" อย่างน้อยหนึ่งครั้ง
Catch - บล็อก "catch" จะจับข้อยกเว้นและสร้างออบเจ็กต์ที่มีข้อมูลข้อยกเว้น
มาทริกเกอร์ข้อยกเว้นกัน:
<?php // สร้างฟังก์ชันที่มีการจัดการข้อยกเว้น การทำงาน เช็คนัม ( $number ) - ถ้า ( $number > 1 ) - โยน ใหม่ ข้อ ยกเว้น ( " ค่าตัวแปรต้องน้อยกว่าหรือเท่ากับ 1 " ) ; กลับ จริง ; } // ทริกเกอร์ข้อยกเว้นใน try block พยายาม - checkNum ( 2 ) ; // หากมีการยกเว้น ข้อความต่อไปนี้จะไม่ถูกส่งออก เสียงสะท้อน ' ถ้าเนื้อหานี้ ออก มา ให้อธิบายตัวแปร $number ' } // จับข้อยกเว้น จับ ( ยกเว้น $อี ) - เสียงสะท้อน ' ข้อความ: ' . $e - > getMessage ( ) ; -
รหัสข้างต้นจะได้รับข้อผิดพลาดคล้ายกับสิ่งนี้:
ข้อความ: ค่าตัวแปรต้องน้อยกว่าหรือเท่ากับ 1
โค้ดด้านบนแสดงข้อยกเว้นและจับได้:
สร้างฟังก์ชัน checkNum() ตรวจพบว่าตัวเลขมากกว่า 1 หรือไม่ หากเป็นเช่นนั้น ให้ระบุข้อยกเว้น
เรียกใช้ฟังก์ชัน checkNum() ในบล็อก "ลอง"
ข้อยกเว้นในฟังก์ชัน checkNum() ถูกส่งออกไป
บล็อกโค้ด "catch" ได้รับข้อยกเว้นและสร้างอ็อบเจ็กต์ ($e) ที่มีข้อมูลข้อยกเว้น
ส่งออกข้อความแสดงข้อผิดพลาดจากข้อยกเว้นนี้โดยการเรียก $e->getMessage() จากวัตถุข้อยกเว้นนี้
อย่างไรก็ตาม เพื่อให้เป็นไปตามหลักการ "ทุกการโยนต้องสอดคล้องกับ catch" คุณสามารถตั้งค่าตัวจัดการข้อยกเว้นระดับบนสุดเพื่อจัดการกับข้อผิดพลาดที่ไม่ได้รับ
การสร้างตัวจัดการข้อยกเว้นแบบกำหนดเองนั้นง่ายมาก เราเพียงแค่สร้างคลาสเฉพาะที่สามารถเรียกใช้ฟังก์ชันได้เมื่อมีข้อยกเว้นเกิดขึ้นใน PHP คลาสนี้ต้องเป็นส่วนขยายของคลาสข้อยกเว้น
คลาส customException แบบกำหนดเองนี้สืบทอดคุณสมบัติทั้งหมดของคลาสยกเว้นของ PHP และคุณสามารถเพิ่มฟังก์ชันแบบกำหนดเองลงไปได้
เราเริ่มต้นด้วยการสร้างคลาส customException:
<?php ระดับ ข้อยกเว้นแบบกำหนดเอง ขยาย ข้อยกเว้น - สาธารณะ การทำงาน ข้อความแสดงข้อผิดพลาด ( ) - // ข้อความแสดงข้อผิดพลาด $ errorMsg = ' หมายเลข บรรทัด ข้อ ผิด พลาด ' . $ this - > getLine ( ) ' ที่อยู่อีเมลที่ถูก ต้อง ' ; $ errorMsg ; - $email = " someone@ example ...com " ; - // ตรวจจับอีเมล ถ้า ( filter_var ( $email , FILTER_VALIDATE_EMAIL ) === FALSE ) - // หากเป็นที่อยู่อีเมลที่ผิดกฎหมาย ให้ระบุข้อยกเว้น โยน ใหม่ customException ( $ อีเมล ) ; - จับ ( customException $อี ) - // แสดงข้อความที่กำหนดเอง เสียงสะท้อน $e -> ข้อความ แสดง ข้อผิดพลาด ( ) ; -
คลาสใหม่นี้เป็นสำเนาของคลาสข้อยกเว้นเก่า พร้อมด้วยฟังก์ชัน errorMessage() เพียงเพราะมันเป็นการคัดลอกของคลาสเก่า มันจึงสืบทอดคุณสมบัติและวิธีการจากคลาสเก่า และเราสามารถใช้วิธีการของคลาสข้อยกเว้น เช่น getLine(), getFile() และ getMessage()
รหัสข้างต้นส่งข้อยกเว้นและจับมันผ่านคลาสข้อยกเว้นที่กำหนดเอง:
คลาส customException() ถูกสร้างขึ้นเป็นส่วนขยายของคลาสข้อยกเว้นเก่า ด้วยวิธีนี้จะสืบทอดคุณสมบัติและวิธีการทั้งหมดของคลาสยกเว้นเก่า
สร้างฟังก์ชัน errorMessage() ถ้าที่อยู่อีเมลไม่ถูกต้อง ฟังก์ชันนี้จะส่งกลับข้อความแสดงข้อผิดพลาด
ตั้งค่าตัวแปร $email เป็นสตริงที่อยู่อีเมลที่ผิดกฎหมาย
บล็อกโค้ด "ลอง" ถูกดำเนินการและมีข้อยกเว้นเกิดขึ้นเนื่องจากที่อยู่อีเมลไม่ถูกต้อง
บล็อกโค้ด "catch" จะจับข้อยกเว้นและแสดงข้อความแสดงข้อผิดพลาด
คุณสามารถใช้ข้อยกเว้นหลายรายการสำหรับสคริปต์เพื่อตรวจจับหลายสถานการณ์
คุณสามารถใช้บล็อกโค้ด if..else หลายบล็อก หรือบล็อกโค้ดสวิตช์ หรือซ้อนข้อยกเว้นหลายรายการได้ ข้อยกเว้นเหล่านี้สามารถใช้คลาสข้อยกเว้นที่แตกต่างกันและส่งกลับข้อความแสดงข้อผิดพลาดที่แตกต่างกัน:
<?php ระดับ ข้อยกเว้นแบบกำหนดเอง ขยาย ข้อยกเว้น - สาธารณะ การทำงาน ข้อความแสดงข้อผิดพลาด ( ) - // ข้อความแสดงข้อผิดพลาด $ errorMsg = ' หมายเลข บรรทัด ข้อ ผิด พลาด ' . $ this - > getLine ( ) ' ที่อยู่อีเมลที่ถูก ต้อง ' ; $ errorMsg ; - $ email = " [email protected] " ; - // ตรวจจับอีเมล ถ้า ( filter_var ( $email , FILTER_VALIDATE_EMAIL ) === FALSE ) - // หากเป็นที่อยู่อีเมลที่ผิดกฎหมาย ให้ระบุข้อยกเว้น โยน ใหม่ customException ( $ อีเมล ) ; // ตรวจสอบว่า "ตัวอย่าง" อยู่ในที่อยู่อีเมลหรือไม่ ถ้า ( strpos ( $email , " ตัวอย่าง " ) !== FALSE ) - โยน ใหม่ ข้อ ยกเว้น ( " $email คือกล่องจดหมายตัวอย่าง " ) ; - จับ ( customException $อี ) - เสียงสะท้อน $e -> ข้อความ แสดง ข้อผิดพลาด ( ) ; จับ ( ยกเว้น $อี ) - เสียงสะท้อน $e - > getMessage ( ) ; -
โค้ดด้านบนจะทดสอบสองเงื่อนไขและส่งข้อยกเว้นหากเงื่อนไขใดเงื่อนไขหนึ่งไม่เป็นความจริง:
คลาส customException() ถูกสร้างขึ้นเป็นส่วนขยายของคลาสข้อยกเว้นเก่า ด้วยวิธีนี้จะสืบทอดคุณสมบัติและวิธีการทั้งหมดของคลาสยกเว้นเก่า
สร้างฟังก์ชัน errorMessage() ถ้าที่อยู่อีเมลไม่ถูกต้อง ฟังก์ชันนี้จะส่งกลับข้อความแสดงข้อผิดพลาด
ตั้งค่าตัวแปร $email ให้เป็นสตริงที่เป็นที่อยู่อีเมลที่ถูกต้อง แต่มีสตริง "example"
ดำเนินการบล็อคโค้ด "ลอง" และในเงื่อนไขแรก จะไม่มีข้อยกเว้นเกิดขึ้น
เนื่องจากอีเมลมีสตริง "example" เงื่อนไขที่สองจะทำให้เกิดข้อยกเว้น
บล็อก "catch" จะจับข้อยกเว้นและแสดงข้อความแสดงข้อผิดพลาดที่เหมาะสม
หากคลาส customException ส่งข้อยกเว้น แต่ตรวจไม่พบ customException จะตรวจพบเฉพาะข้อยกเว้นพื้นฐานเท่านั้น ข้อยกเว้นจะถูกจัดการที่นั่น
บางครั้ง เมื่อมีการส่งข้อยกเว้น คุณอาจต้องการจัดการให้แตกต่างไปจากมาตรฐาน ข้อยกเว้นสามารถถูกโยนอีกครั้งในบล็อก "catch"
สคริปต์ควรซ่อนข้อผิดพลาดของระบบจากผู้ใช้ ข้อผิดพลาดของระบบอาจมีความสำคัญสำหรับโปรแกรมเมอร์ แต่ผู้ใช้ไม่สนใจข้อผิดพลาดเหล่านี้ เพื่อให้ผู้ใช้ง่ายขึ้น คุณสามารถส่งข้อยกเว้นอีกครั้งด้วยข้อความที่เป็นมิตรต่อผู้ใช้:
<?php ระดับ ข้อยกเว้นแบบกำหนดเอง ขยาย ข้อยกเว้น - สาธารณะ การทำงาน ข้อความแสดงข้อผิดพลาด ( ) - // ข้อความแสดงข้อผิดพลาด $errorMsg = $this -> getMessage ( ) ' ไม่ใช่ ที่ อยู่ อีเมล ที่ถูกต้อง ' ; กลับ $ errorMsg ; - $ email = " [email protected] " ; - พยายาม - // ตรวจสอบว่า "ตัวอย่าง" อยู่ในที่อยู่อีเมลหรือไม่ ถ้า ( strpos ( $email , " ตัวอย่าง " ) !== FALSE ) - // หากเป็นที่อยู่อีเมลที่ผิดกฎหมาย ให้ระบุข้อยกเว้น โยน ใหม่ ข้อยกเว้น ( $ อีเมล ) ; - จับ ( ยกเว้น $อี ) - // โยนข้อยกเว้นอีกครั้ง โยน ใหม่ customException ( $ อีเมล ) ; - จับ ( customException $อี ) - // แสดงข้อมูลที่กำหนดเอง เสียงสะท้อน $e -> ข้อความ แสดง ข้อผิดพลาด ( ) ; -
รหัสข้างต้นตรวจพบว่าสตริง "ตัวอย่าง" มีอยู่ในที่อยู่อีเมลหรือไม่ หากเป็นเช่นนั้น ให้ส่งข้อยกเว้นอีกครั้ง:
คลาส customException() ถูกสร้างขึ้นเป็นส่วนขยายของคลาสข้อยกเว้นเก่า ด้วยวิธีนี้จะสืบทอดคุณสมบัติและวิธีการทั้งหมดของคลาสยกเว้นเก่า
สร้างฟังก์ชัน errorMessage() ถ้าที่อยู่อีเมลไม่ถูกต้อง ฟังก์ชันนี้จะส่งกลับข้อความแสดงข้อผิดพลาด
ตั้งค่าตัวแปร $email ให้เป็นสตริงที่เป็นที่อยู่อีเมลที่ถูกต้อง แต่มีสตริง "example"
บล็อก "ลอง" มีบล็อก "ลอง" อีกบล็อกหนึ่งเพื่อให้สามารถส่งข้อยกเว้นอีกครั้งได้
เนื่องจากอีเมลมีสตริง "example" ข้อยกเว้นจึงถูกทริกเกอร์
บล็อกโค้ด "catch" จะจับข้อยกเว้นและสร้าง "customException" ใหม่
ตรวจพบ "customException" และข้อความแสดงข้อผิดพลาดปรากฏขึ้น
หากไม่พบข้อยกเว้นในบล็อก "ลอง" ปัจจุบัน มันจะค้นหาบล็อกที่จับในระดับที่สูงกว่า
ฟังก์ชัน set_Exception_handler() ตั้งค่าฟังก์ชันที่ผู้ใช้กำหนดซึ่งจัดการข้อยกเว้นที่ไม่ถูกตรวจจับทั้งหมด
<?php การทำงาน myException ( $ข้อยกเว้น ) - เสียงสะท้อน " <b>ข้อยกเว้น:</b> " , $ ข้อยกเว้น -> getMessage ( ) ; set_Exception_handler ( ' myException ' ) ; ใหม่ ข้อยกเว้น ( ' เกิดข้อยกเว้นที่ไม่ถูกตรวจจับ ' ) ; ?>
ผลลัพธ์ของโค้ดด้านบนมีลักษณะดังนี้:
ข้อยกเว้น: เกิดข้อยกเว้นที่ไม่ได้รับการตรวจสอบ
ในโค้ดข้างต้น ไม่มีบล็อก "catch" แต่จะมีการทริกเกอร์ตัวจัดการข้อยกเว้นระดับบนสุดแทน ควรใช้ฟังก์ชันนี้เพื่อตรวจจับข้อยกเว้นที่ไม่ถูกตรวจจับทั้งหมด
รหัสที่ต้องมีการจัดการข้อยกเว้นควรวางไว้ภายในบล็อก try เพื่อตรวจจับข้อยกเว้นที่อาจเกิดขึ้น
แต่ละบล็อกลองหรือโยนจะต้องมีบล็อกจับที่สอดคล้องกันอย่างน้อยหนึ่งบล็อก
ใช้บล็อก catch หลายรายการเพื่อตรวจจับข้อยกเว้นประเภทต่างๆ
ข้อยกเว้นสามารถถูกโยนทิ้ง (โยนใหม่) ใน catch block ภายใน try block
กล่าวโดยย่อ: หากเกิดข้อยกเว้น คุณต้องจับมันให้ได้