การจัดการข้อยกเว้น PHP
ข้อยกเว้นสำหรับการเปลี่ยนข้อผิดพลาดสคริปต์เกิดขึ้นเมื่อไหลปกติที่ระบุ
อะไรคือสิ่งที่ผิดปกติ
PHP 5 ข้อเสนอวิธีการใหม่สำหรับจัดการข้อผิดพลาดเชิงวัตถุ
การจัดการข้อยกเว้นจะใช้เมื่อเกิดข้อผิดพลาดที่ระบุ (ยกเว้น) เกิดขึ้นในการเปลี่ยนแปลงการไหลปกติของสคริปต์ สภาพนี้เรียกว่าเป็นข้อยกเว้น
เมื่อมีข้อยกเว้นจะถูกเรียกมักจะเกิดขึ้น:
- รัฐรหัสปัจจุบันจะถูกบันทึกไว้
- การเรียกใช้โค้ดจะเปลี่ยนไป (กำหนดเอง) ฟังก์ชั่นการจัดการข้อยกเว้นที่กำหนดไว้ล่วงหน้า
- ในบางกรณีหน่วยประมวลผลอาจจะเริ่มต้นใหม่จากโค้ดที่เก็บไว้ในรหัสสถานะยุติการดำเนินการสคริปต์หรือยังคงสคริปต์จากรหัสสถานที่ที่แตกต่างกัน
เราจะแสดงวิธีการจัดการข้อผิดพลาดที่แตกต่างกัน
- ยกเว้นการใช้งานพื้นฐาน
- การสร้างจัดการข้อยกเว้นที่กำหนดเอง
- ข้อยกเว้นหลาย
- Rethrows
- ระดับบนสุดชุดการจัดการข้อยกเว้น
หมายเหตุ: ข้อยกเว้นควรใช้เฉพาะในกรณีที่มีข้อผิดพลาดก็ไม่ควรนำมาใช้ในจุดที่กำหนดเพื่อข้ามไปยังสถานที่อื่นในรหัส
ยกเว้นการใช้งานพื้นฐาน
เมื่อยกเว้นจะโยนรหัสที่ตามมาไม่ได้ดำเนินการต่อไป, PHP จะพยายามหาจับคู่ "จับ" บล็อก
หากมีข้อยกเว้นไม่ได้ถูกจับ แต่ไม่ได้มีการใช้ set_exception_handler (ที่) สำหรับการรักษาที่สอดคล้องกันแล้วข้อผิดพลาดร้ายแรง (ข้อผิดพลาดร้ายแรง) เกิดขึ้นและการส่งออก "Uncaught ข้อยกเว้น" (uncaught ข้อยกเว้น) ข้อความผิดพลาด
ลองโยนยกเว้น แต่ไม่ได้จับมัน:
<?php // 创建一个有异常处理的函数 function checkNum($number) { if($number>1) { throw new Exception("Value must be 1 or below"); } return true; } // 触发异常 checkNum(2); ?>
โค้ดข้างต้นจะได้รับข้อผิดพลาดที่คล้ายกันนี้:
Fatal error: Uncaught exception 'Exception' with message 'Value must be 1 or below' in /www/w3big/test/test.php:7 Stack trace: #0 /www/w3big/test/test.php(13): checkNum(2) #1 {main} thrown in /www/w3big/test/test.php on line 7
ลองและจับโยน
เพื่อหลีกเลี่ยงข้อผิดพลาดที่ปรากฏในตัวอย่างข้างต้นเราต้องสร้างรหัสที่เหมาะสมในการจัดการกับข้อยกเว้น
รหัสข้อยกเว้นการจัดการที่เหมาะสมควรจะรวมถึง:
- ลอง - ฟังก์ชั่นการใช้ที่ผิดปกติควรจะอยู่ใน "ลอง" บล็อก หากไม่มีข้อยกเว้นจะถูกเรียกรหัสจะยังคงเป็นปกติ แต่ถ้ามีข้อยกเว้นจะถูกเรียกก็จะโยนข้อยกเว้น
- โยน - ในวิธีการที่จะเรียกบทบัญญัติข้อยกเว้น แต่ละ "โยน" จะต้องสอดคล้องกับอย่างน้อยหนึ่ง "จับ"
- จับ - "จับ" บล็อก catches ข้อยกเว้นและสร้างวัตถุที่มีข้อความข้อยกเว้น
ขอเรียกข้อยกเว้น:
<?php // 创建一个有异常处理的函数 function checkNum($number) { if($number>1) { throw new Exception("变量值必须小于等于 1"); } return true; } // 在 try 块 触发异常 try { checkNum(2); // 如果抛出异常,以下文本不会输出 echo '如果输出该内容,说明 $number 变量'; } // 捕获异常 catch(Exception $e) { echo 'Message: ' .$e->getMessage(); } ?>
รหัสข้างต้นจะได้รับข้อผิดพลาดเช่นนี้:
Message: 变量值必须小于等于 1
ตัวอย่างอธิบาย:
รหัสข้างต้นพ่นยกเว้นและจับมัน:
- สร้าง checkNum () ฟังก์ชัน ตรวจพบว่าเป็นจำนวนที่มีค่ามากกว่าหนึ่ง ถ้ามันเป็นข้อยกเว้นจะถูกโยนทิ้ง
- โทร checkNum () ฟังก์ชันใน "ลอง" บล็อก
- checkNum () ฟังก์ชั่นยกเว้นจะถูกโยนทิ้ง
- "จับ" บล๊อคได้รับการยกเว้นและการสร้างวัตถุที่มีข้อมูลเกี่ยวกับการยกเว้น ($ จ)
- โดยการเรียก $ E- จากข้อยกเว้นวัตถุนี้> getMessage () ออกจากข้อผิดพลาดในการยกเว้น
อย่างไรก็ตามในการที่จะปฏิบัติตาม "โยนทุกจะต้องสอดคล้องกับการจับหลักการ" คุณสามารถตั้งค่าการจัดการข้อยกเว้นระดับบนสุดที่จะจัดการกับข้อผิดพลาดที่ไม่ได้รับ
สร้างคลาสยกเว้นที่กำหนดเอง
การสร้างจัดการข้อยกเว้นที่กำหนดเองเป็นเรื่องง่ายมาก เราเพียงแค่สร้างชั้นพิเศษเมื่อเกิดข้อยกเว้นใน PHP คุณสามารถเรียกฟังก์ชั่น ชั้นจะต้องเป็นส่วนหนึ่งของชั้นข้อยกเว้น
ชั้นยกเว้นที่กำหนดเองสืบทอดคุณลักษณะทั้งหมดที่กำหนดไว้ในระดับยกเว้น PHP, คุณอาจต้องการที่จะเพิ่มฟังก์ชั่นที่กำหนดเอง
เริ่มต้นด้วยการสร้างการเรียนการยกเว้น
<?php class customException extends Exception { public function errorMessage() { // 错误信息 $errorMsg = '错误行号 '.$this->getLine().' in '.$this->getFile() .': <b>'.$this->getMessage().'</b> 不是一个合法的 E-Mail 地址'; return $errorMsg; } } $email = "[email protected]"; try { // 检测邮箱 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) { // 如果是个不合法的邮箱地址,抛出异常 throw new customException($email); } } catch (customException $e) { //display custom message echo $e->errorMessage(); } ?>
คลาสใหม่นี้เป็นสำเนาของชนชั้นยกเว้นเก่าบวก errormessage () ฟังก์ชัน เพราะมันเป็นสำเนาของชนชั้นเก่าจึงสืบทอดจากคุณสมบัติชั้นเก่าและวิธีการที่เราสามารถใช้วิธีการเรียนการยกเว้นเช่น getline () getFile () และ getMessage ()
ตัวอย่างอธิบาย:
รหัสข้างต้นพ่นยกเว้นและผ่านระดับข้อยกเว้นที่กำหนดเองที่จะจับมัน
- customException () รุ่นที่เป็นส่วนขยายของชั้นยกเว้นเก่าที่จะสร้าง เพื่อที่จะสืบทอดคุณลักษณะทั้งหมดและวิธีการของชนชั้นยกเว้นเก่า
- สร้าง errormessage () ฟังก์ชัน หากที่อยู่อีเมลไม่ถูกต้องฟังก์ชันจะส่งกลับข้อผิดพลาด
- ตัวแปร $ อีเมลถูกตั้งค่าเป็นสตริงอยู่ไม่ถูกต้อง E-mail
- การดำเนินงานของ "ลอง" บล็อกตั้งแต่ที่อยู่อีเมลที่ไม่ถูกต้องและดังนั้นจึงพ่นยกเว้น
- "จับ" บล็อกที่จะจับข้อยกเว้นและแสดงข้อความผิดพลาด
ข้อยกเว้นหลาย
คุณสามารถใช้ข้อยกเว้นหลายคนเป็นสคริปต์เพื่อตรวจสอบความหลากหลายของสถานการณ์
คุณสามารถใช้บล็อกหลาย if..else หรือบล็อกการใช้รหัสหรือรังหลายข้อยกเว้น ข้อยกเว้นเหล่านี้สามารถใช้การเรียนการยกเว้นที่แตกต่างกันและกลับข้อความผิดพลาดที่แตกต่างกัน
<?php class customException extends Exception { public function errorMessage() { // 错误信息 $errorMsg = '错误行号 '.$this->getLine().' in '.$this->getFile() .': <b>'.$this->getMessage().'</b> 不是一个合法的 E-Mail 地址'; return $errorMsg; } } $email = "[email protected]"; try { // 检测邮箱 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) { // 如果是个不合法的邮箱地址,抛出异常 throw new customException($email); } // 检测 "example" 是否在邮箱地址中 if(strpos($email, "example") !== FALSE) { throw new Exception("$email 是 example 邮箱"); } } catch (customException $e) { echo $e->errorMessage(); } catch(Exception $e) { echo $e->getMessage(); } ?>
ตัวอย่างอธิบาย:
รหัสข้างต้นการทดสอบสองเงื่อนไขถ้าคนใดคนหนึ่งสภาพไม่พอใจแล้วโยนข้อยกเว้น:
- customException () รุ่นที่เป็นส่วนขยายของชั้นยกเว้นเก่าที่จะสร้าง เพื่อที่จะสืบทอดคุณลักษณะทั้งหมดและวิธีการของชนชั้นยกเว้นเก่า
- สร้าง errormessage () ฟังก์ชัน หากที่อยู่อีเมลไม่ถูกต้องฟังก์ชันจะส่งกลับข้อผิดพลาด
- ตัวแปร $ อีเมลถูกตั้งค่าเป็นสตริงที่เป็นที่อยู่อีเมลที่ถูกต้อง แต่มีสตริง "เช่น"
- การดำเนินงานของ "ลอง" บล็อกของรหัสในสภาพที่แรกไม่มีข้อยกเว้นจะถูกโยนทิ้ง
- ตั้งแต่อีเมลที่ประกอบด้วยสตริง "ตัวอย่างเช่น" เงื่อนไขที่สองเรียกข้อยกเว้น
- "จับ" บล็อก catches ข้อยกเว้นและแสดงข้อความข้อผิดพลาดที่เหมาะสม
หากยกเว้นระดับ customException จะถูกโยนทิ้ง แต่ไม่ได้ติด customException จับเพียงข้อยกเว้นฐานที่จับข้อยกเว้น
Rethrows
บางครั้งเมื่อยกเว้นจะโยนคุณอาจต้องการที่จะแตกต่างจากวิธีมาตรฐานในการจัดการกับมัน อีกครั้งอาจจะโยนใน "จับ" บล็อก
สคริปต์ที่ควรจะซ่อนจากข้อผิดพลาดของระบบของผู้ใช้ สำหรับโปรแกรมเมอร์ข้อผิดพลาดของระบบอาจมีความสำคัญ แต่ผู้ใช้ไม่ได้สนใจในตัวเขา ที่จะทำให้มันง่ายขึ้นสำหรับผู้ที่จะใช้คุณสามารถโยนข้อยกเว้นอีกครั้งกับข้อความใช้ง่ายพอสมควร:
<?php class customException extends Exception { public function errorMessage() { // 错误信息 $errorMsg = $this->getMessage().' 不是一个合法的 E-Mail 地址。'; return $errorMsg; } } $email = "[email protected]"; try { try { // 检测 "example" 是否在邮箱地址中 if(strpos($email, "example") !== FALSE) { // 如果是个不合法的邮箱地址,抛出异常 throw new Exception($email); } } catch(Exception $e) { // 重新抛出异常 throw new customException($email); } } catch (customException $e) { // 显示自定义信息 echo $e->errorMessage(); } ?>
ตัวอย่างอธิบาย:
รหัสข้างต้นมีการตรวจพบใน e-mail address ถ้ามีสตริง "เช่น" ถ้ามีอีกครั้งยกเว้นจะโยน:
- customException () รุ่นที่เป็นส่วนขยายของชั้นยกเว้นเก่าที่จะสร้าง เพื่อที่จะสืบทอดคุณลักษณะทั้งหมดและวิธีการของชนชั้นยกเว้นเก่า
- สร้าง errormessage () ฟังก์ชัน หากที่อยู่อีเมลไม่ถูกต้องฟังก์ชันจะส่งกลับข้อผิดพลาด
- ตัวแปร $ อีเมลถูกตั้งค่าเป็นสตริงที่เป็นที่อยู่อีเมลที่ถูกต้อง แต่มีสตริง "เช่น"
- "ลอง" บล็อกมีอีกบล็อก "ลอง" ของรหัสเพื่อให้คุณสามารถโยนข้อยกเว้นอีกครั้ง
- ตั้งแต่อีเมลที่ประกอบด้วยสตริง "เช่น" และดังนั้นจึงก่อให้เกิดข้อยกเว้น
- "จับ" บล็อกที่จะจับข้อยกเว้นและอีกโยน "customException"
- จับ "customException" และแสดงข้อความแสดงข้อผิดพลาด
หากมีข้อยกเว้นไม่ได้ถูกจับในปัจจุบัน "ลอง" บล็อกจะมองหาจับบล็อกในระดับที่สูง
ระดับบนสุดชุดการจัดการข้อยกเว้น
set_exception_handler () ฟังก์ชันที่สามารถตั้งค่าในการจัดการข้อยกเว้น uncaught ทั้งหมดของฟังก์ชั่นที่ผู้ใช้กำหนด
<?php function myException($exception) { echo "<b>Exception:</b> " , $exception->getMessage(); } set_exception_handler('myException'); throw new Exception('Uncaught Exception occurred'); ?>
การส่งออกของโค้ดข้างต้นจะเป็นดังนี้:
Exception: Uncaught Exception occurred
ในรหัสข้างต้นไม่มี "จับ" บล็อก แต่ระดับบนสุดจัดการข้อยกเว้นเรียก ฟังก์ชั่นนี้ควรจะใช้ในการจับข้อยกเว้น uncaught ทั้งหมด
กฎข้อยกเว้น
- รหัสการจัดการข้อยกเว้นจะต้องมีการวางไว้ในบล็อกลองเพื่อที่จะจับข้อยกเว้นที่อาจเกิดขึ้น
- แต่ละบล็อกหรือลองโยนรหัสจะต้องมีอย่างน้อยหนึ่งที่สอดคล้องกันจับบล็อก
- คุณสามารถใช้จับหลายบล็อกที่จะจับความแตกต่างของข้อยกเว้น
- อาจจะอยู่ในการป้องกันรหัสลองพ่นจับบล็อก (โยนอีกครั้ง) ยกเว้น
ในระยะสั้น: ถ้าคุณโยนยกเว้นคุณจะต้องจับมัน