تُستخدم الاستثناءات لتغيير التدفق الطبيعي للبرنامج النصي عند حدوث خطأ محدد.
يوفر PHP 5 أسلوبًا جديدًا موجهًا للكائنات لمعالجة الأخطاء.
يتم استخدام معالجة الاستثناء لتغيير التدفق الطبيعي للبرنامج النصي عند حدوث حالة خطأ (استثناء) محددة. هذا الوضع يسمى استثناء.
عندما يتم تشغيل استثناء، يحدث عادةً ما يلي:
يتم حفظ حالة الكود الحالية
يتم تحويل تنفيذ التعليمات البرمجية إلى وظيفة معالج الاستثناءات المحددة مسبقًا (المخصصة).
اعتمادًا على الموقف، قد يقوم المعالج بإعادة تشغيل تنفيذ التعليمات البرمجية من حالة التعليمات البرمجية المحفوظة، أو إنهاء تنفيذ البرنامج النصي، أو متابعة تنفيذ البرنامج النصي من موقع آخر في التعليمات البرمجية.
سنعرض طرقًا مختلفة لمعالجة الأخطاء:
الاستخدام الأساسي للاستثناءات
إنشاء معالج استثناء مخصص
استثناءات متعددة
إعادة الاستثناء
قم بتعيين معالج الاستثناء ذي المستوى الأعلى
ملاحظة: يجب استخدام الاستثناءات فقط في حالات الخطأ ولا يجب استخدامها للانتقال إلى موقع آخر في الكود عند نقطة محددة.
عندما يتم طرح استثناء، لن يستمر تنفيذ التعليمات البرمجية التالية، وسيحاول PHP العثور على كتلة "التقاط" مطابقة من التعليمات البرمجية.
إذا لم يتم اكتشاف الاستثناء ولم تتم معالجته وفقًا لذلك باستخدام set_exception_handler()، فسيحدث خطأ فادح (خطأ فادح) وسيتم إخراج رسالة خطأ "Uncaught Exception".
دعنا نحاول طرح استثناء دون التقاطه:
<?php // إنشاء دالة مع معالجة الاستثناءات وظيفة رقم الاختيار ( رقم $ ) { إذا ( رقم $ > 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
لتجنب الخطأ الموضح في المثال أعلاه، نحتاج إلى إنشاء تعليمات برمجية مناسبة للتعامل مع الاستثناءات.
يجب أن يتضمن رمز معالجة الاستثناء المناسب ما يلي:
حاول - يجب أن تكون الوظائف التي تستخدم الاستثناءات داخل كتلة "المحاولة". إذا لم يتم تشغيل أي استثناء، فسيستمر تنفيذ التعليمات البرمجية كالمعتاد. ولكن إذا تم تشغيل استثناء، فسيتم طرح استثناء.
رمي - يحدد كيفية تشغيل الاستثناء. يجب أن تتوافق كل "رمية" مع "مسكة" واحدة على الأقل.
Catch - تلتقط كتلة "catch" الاستثناء وتقوم بإنشاء كائن يحتوي على معلومات الاستثناء.
لنبدأ الاستثناء:
<?php // إنشاء دالة مع معالجة الاستثناءات وظيفة رقم الاختيار ( رقم $ ) { إذا ( رقم $ > 1 ) { يرمي جديد استثناء ( " قيمة المتغير يجب أن تكون أقل من أو تساوي 1 " ) ؛ } يعود حقيقي ؛ } // تشغيل الاستثناء في كتلة المحاولة يحاول { checkNum ( 2 ) ; // إذا تم طرح استثناء، فلن يتم إخراج النص التالي صدى ' إذا تم إخراج هذا المحتوى، قم بشرح المتغير $number ' } // قبض على الاستثناء قبض ( استثناء $e ) { صدى ' الرسالة : ' $e - > getMessage ( ) } ?>
سوف يحصل الكود أعلاه على خطأ مشابه لما يلي:
الرسالة: يجب أن تكون قيمة المتغير أقل من أو تساوي 1
يطرح الكود أعلاه استثناءً ويلتقطه:
إنشاء وظيفة checkNum(). يكتشف ما إذا كان الرقم أكبر من 1. إذا كان الأمر كذلك، رمي استثناء.
قم باستدعاء الدالة checkNum() في كتلة "المحاولة".
تم طرح الاستثناء في الدالة checkNum().
تتلقى كتلة التعليمات البرمجية "catch" الاستثناء وتقوم بإنشاء كائن ($e) يحتوي على معلومات الاستثناء.
قم بإخراج رسالة الخطأ من هذا الاستثناء عن طريق استدعاء $e->getMessage() من كائن الاستثناء هذا.
ومع ذلك، من أجل اتباع مبدأ "كل رمية يجب أن تتوافق مع الالتقاط"، يمكنك إعداد معالج استثناء عالي المستوى للتعامل مع الأخطاء المفقودة.
يعد إنشاء معالجات استثناء مخصصة أمرًا بسيطًا للغاية. لقد قمنا ببساطة بإنشاء فئة متخصصة يمكن استدعاء وظائفها عند حدوث استثناء في PHP. يجب أن تكون هذه الفئة امتدادًا لفئة الاستثناء.
ترث فئة customException المخصصة جميع خصائص فئة استثناء PHP، ويمكنك إضافة وظائف مخصصة إليها.
نبدأ بإنشاء فئة customException:
<?php فصل customException يمتد استثناء { عام وظيفة رسالة الخطأ ( ) { // رسالة خطأ $errorMsg = ' رقم سطر الخطأ ' . $this - > getLine ( ) ' في ' $ this - > getFile ( ) ' : $ this - > getMessage ( ) </b> لا عنوان بريد إلكتروني صالح ' ; $ خطأالرسالة } } $email = " someone@ example ...com " ; { // كشف البريد الإلكتروني إذا ( filter_var ( $email , FILTER_VALIDATE_EMAIL ) === FALSE ) { // إذا كان عنوان البريد الإلكتروني غير قانوني، فقم بطرح استثناء يرمي جديد customException ( $ email ) } } يمسك ( استثناء مخصص $e ) { // عرض رسالة مخصصة صدى $e -> رسالة الخطأ ( ) ; ?>
هذه الفئة الجديدة هي نسخة من فئة الاستثناء القديمة، بالإضافة إلى وظيفة errorMessage(). لمجرد أنها نسخة من الفئة القديمة، فإنها ترث خصائص وأساليب من الفئة القديمة، ويمكننا استخدام أساليب فئة الاستثناء، مثل getLine() وgetFile() وgetMessage().
يطرح الكود أعلاه استثناءً ويلتقطه من خلال فئة استثناء مخصصة:
تم إنشاء فئة customException () كامتداد لفئة الاستثناء القديمة. بهذه الطريقة يرث جميع خصائص وأساليب فئة الاستثناء القديمة.
إنشاء وظيفة errorMessage (). إذا كان عنوان البريد الإلكتروني غير صالح، تقوم هذه الوظيفة بإرجاع رسالة خطأ.
قم بتعيين متغير البريد الإلكتروني $ إلى سلسلة عنوان بريد إلكتروني غير قانوني.
يتم تنفيذ كتلة التعليمات البرمجية "المحاولة" ويتم طرح استثناء لأن عنوان البريد الإلكتروني غير صالح.
تكتشف كتلة التعليمات البرمجية "catch" الاستثناء وتعرض رسالة خطأ.
يمكنك استخدام استثناءات متعددة لبرنامج نصي لاكتشاف مواقف متعددة.
يمكنك استخدام عدة كتل برمجية if..else، أو كتلة تعليمات برمجية للتبديل، أو تداخل استثناءات متعددة. يمكن لهذه الاستثناءات استخدام فئات استثناءات مختلفة وإرجاع رسائل خطأ مختلفة:
<?php فصل customException يمتد استثناء { عام وظيفة رسالة الخطأ ( ) { // رسالة خطأ $errorMsg = ' رقم سطر الخطأ ' . $this - > getLine ( ) ' في ' $ this - > getFile ( ) ' : $ this - > getMessage ( ) </b> لا عنوان بريد إلكتروني صالح ' ; $ خطأالرسالة } } $ email = " [email protected] " ; { // كشف البريد الإلكتروني إذا ( filter_var ( $email , FILTER_VALIDATE_EMAIL ) === FALSE ) { // إذا كان عنوان البريد الإلكتروني غير قانوني، فقم بطرح استثناء يرمي جديد customException ( $ email ) } // تحقق مما إذا كان "المثال" موجودًا في عنوان البريد الإلكتروني إذا ( strpos ( $email , " example " ) !== FALSE ) { يرمي جديد استثناء ( " $email هو صندوق البريد النموذجي " ) } } يمسك ( استثناء مخصص $e ) { صدى $e -> رسالة الخطأ ( ) ; قبض ( استثناء $e ) { صدى $e - > getMessage ( ) ; ?>
يختبر الكود أعلاه شرطين ويطرح استثناءً إذا لم يكن أي من الشرطين صحيحًا:
تم إنشاء فئة customException () كامتداد لفئة الاستثناء القديمة. بهذه الطريقة يرث جميع خصائص وأساليب فئة الاستثناء القديمة.
إنشاء وظيفة errorMessage (). إذا كان عنوان البريد الإلكتروني غير صالح، تقوم هذه الوظيفة بإرجاع رسالة خطأ.
قم بتعيين متغير البريد الإلكتروني $ إلى سلسلة تمثل عنوان بريد إلكتروني صالحًا ولكنها تحتوي على السلسلة "مثال".
قم بتنفيذ كتلة "المحاولة" من التعليمات البرمجية، وفي الشرط الأول، لن يتم طرح أي استثناء.
وبما أن البريد الإلكتروني يحتوي على السلسلة "مثال"، فإن الشرط الثاني سيؤدي إلى حدوث استثناء.
تلتقط كتلة "catch" الاستثناء وتعرض رسالة خطأ مناسبة.
إذا طرحت فئة customException استثناءً، ولكن لم يتم اكتشاف CustomException، فسيتم اكتشاف الاستثناء الأساسي فقط، وتتم معالجة الاستثناء هناك.
في بعض الأحيان، عند طرح استثناء، قد ترغب في التعامل معه بشكل مختلف عن المعيار. يمكن طرح الاستثناء مرة أخرى في كتلة "الالتقاط".
يجب أن يخفي البرنامج النصي أخطاء النظام عن المستخدم. قد تكون أخطاء النظام مهمة للمبرمجين، لكن المستخدمين غير مهتمين بها. لتسهيل الأمر على المستخدمين، يمكنك طرح الاستثناء مرة أخرى برسالة سهلة الاستخدام:
<?php فصل customException يمتد استثناء { عام وظيفة رسالة الخطأ ( ) { // رسالة خطأ $errorMsg = $this -> getMessage ( ) ' ليس عنوان بريد إلكتروني صالحًا . ' ؛ يعود $ خطأالرسالة } } $ email = " [email protected] " ; { يحاول { // تحقق مما إذا كان "المثال" موجودًا في عنوان البريد الإلكتروني إذا ( strpos ( $email , " example " ) !== FALSE ) { // إذا كان عنوان البريد الإلكتروني غير قانوني، فقم بطرح استثناء يرمي جديد استثناء ( $ email ) } } قبض ( استثناء $e ) { // إعادة طرح الاستثناء يرمي جديد customException ( $ email ) } } يمسك ( استثناء مخصص $e ) { // عرض المعلومات المخصصة صدى $e -> رسالة الخطأ ( ) ; ?>
يكتشف الكود أعلاه ما إذا كانت السلسلة "مثال" موجودة في عنوان البريد الإلكتروني. إذا كان الأمر كذلك، قم بطرح الاستثناء مرة أخرى:
تم إنشاء فئة customException () كامتداد لفئة الاستثناء القديمة. بهذه الطريقة يرث جميع خصائص وأساليب فئة الاستثناء القديمة.
إنشاء وظيفة errorMessage (). إذا كان عنوان البريد الإلكتروني غير صالح، تقوم هذه الوظيفة بإرجاع رسالة خطأ.
قم بتعيين متغير البريد الإلكتروني $ إلى سلسلة تمثل عنوان بريد إلكتروني صالحًا ولكنها تحتوي على السلسلة "مثال".
تحتوي كتلة "المحاولة" على كتلة "محاولة" أخرى بحيث يمكن طرح الاستثناء مرة أخرى.
نظرًا لأن البريد الإلكتروني يحتوي على السلسلة "مثال"، يتم تشغيل الاستثناء.
تلتقط كتلة التعليمات البرمجية "catch" الاستثناء وتعيد طرح "customException".
تم اكتشاف "customException" ويتم عرض رسالة خطأ.
إذا لم يتم اكتشاف الاستثناء في كتلة "المحاولة" الحالية، فسيتم البحث عن كتلة التقاط في مستوى أعلى.
تقوم الدالة set_exception_handler() بتعيين وظيفة معرفة من قبل المستخدم تعالج جميع الاستثناءات التي لم يتم اكتشافها.
<?php وظيفة myException ( $exception ) { صدى " <b>الاستثناء:</b> " , $exception -> getMessage ( ) } ; set_exception_handler ( ' myException ' ) ؛ جديد استثناء ( ' حدث استثناء لم يتم اكتشافه ' ) ;
يبدو إخراج الكود أعلاه كما يلي:
استثناء: حدث استثناء لم يتم اكتشافه
في الكود أعلاه، لا توجد كتلة "التقاط"، وبدلاً من ذلك يتم تشغيل معالج الاستثناء ذي المستوى الأعلى. يجب استخدام هذه الوظيفة لالتقاط كافة الاستثناءات التي لم يتم اكتشافها.
يجب وضع التعليمات البرمجية التي تتطلب معالجة الاستثناءات ضمن كتلة المحاولة لالتقاط الاستثناءات المحتملة.
يجب أن تحتوي كل كتلة محاولة أو رمي على كتلة التقاط مقابلة واحدة على الأقل.
استخدم كتل التقاط متعددة لالتقاط أنواع مختلفة من الاستثناءات.
يمكن طرح الاستثناءات (إعادة طرحها) في كتلة الالتقاط داخل كتلة المحاولة.
باختصار: إذا تم طرح استثناء، فيجب عليك التقاطه.