الفرق بين المراجعتين لصفحة: «PHP/exceptions»

من موسوعة حسوب
< PHP
ط استبدال النص - 'PHP/Exceptions/extending' ب'PHP/exceptions'
ط استبدال النص - 'PHP\/Function\/([^|]*)' ب'PHP/$1'
سطر 6: سطر 6:
يمكن استخدام كتل <code>catch</code> متعدّدة لالتقاط أصناف مختلفة من الاستثناءات. تستمر عملية تنفيذ الشيفرة الاعتيادية (في حال عدم رمي أي استثناء في الكتلة block) بعد آخر كتلة <code>catch</code> معرّفة في الشيفرة. يمكن رمي الاستثناءات (أو إعادة رميها) ضمن الكتلة <code>catch</code>.
يمكن استخدام كتل <code>catch</code> متعدّدة لالتقاط أصناف مختلفة من الاستثناءات. تستمر عملية تنفيذ الشيفرة الاعتيادية (في حال عدم رمي أي استثناء في الكتلة block) بعد آخر كتلة <code>catch</code> معرّفة في الشيفرة. يمكن رمي الاستثناءات (أو إعادة رميها) ضمن الكتلة <code>catch</code>.


لا تنفّذ الشيفرة التي تلي العبارة التي تسبّبت في رمي الاستثناء، وتحاول اللغة العثور على أول كتلة catch مطابقة. في حال عدم التقاط الاستثناء، تطلق اللغة خطأ من نوع PHP مع رسالة ‎‎"Uncaught Exception ..."‎ إلا إذا كان هناك متحكّم معرّف بواسطة الدالة <code>[[PHP/Function/set-exception-handler|set_exception_handler()]]</code>‎.
لا تنفّذ الشيفرة التي تلي العبارة التي تسبّبت في رمي الاستثناء، وتحاول اللغة العثور على أول كتلة catch مطابقة. في حال عدم التقاط الاستثناء، تطلق اللغة خطأ من نوع PHP مع رسالة ‎‎"Uncaught Exception ..."‎ إلا إذا كان هناك متحكّم معرّف بواسطة الدالة <code>[[PHP/set-exception-handler|set_exception_handler()]]</code>‎.


في الإصدار 7.1 وما بعده من اللغة، يمكن لكتلة <code>catch</code> أن تحدّد استثناءات متعددة باستخدام الرمز (<code>|</code>). هذه الميزة مفيدة عندما تتعامل اللغة بالطريقة نفسها مع استثناءات مختلفة من تسلسلات هرمية لأصناف مختلفة.
في الإصدار 7.1 وما بعده من اللغة، يمكن لكتلة <code>catch</code> أن تحدّد استثناءات متعددة باستخدام الرمز (<code>|</code>). هذه الميزة مفيدة عندما تتعامل اللغة بالطريقة نفسها مع استثناءات مختلفة من تسلسلات هرمية لأصناف مختلفة.

مراجعة 03:43، 4 أبريل 2018

يتضمّن الإصدار الخامس من PHP نموذج استثناءات مشابهًا للغات البرمجية الأخرى. يمكن رمي الاستثناء والتقاطه في PHP، ويمكن إحاطة الشيفرة بكتلة try لتسهيل عملية التقاط الاستثناءات المحتملة، ويجب أن ترتبط بكل كتلة try إما كتلة catch أو finally واحدة على الأقل.

يجب أن يكون كائن الاستثناء المرمي نسخة من الصنف Exception أو صنفًا متفرعًا منه، ويؤدي رمي كائن لا ينتمي إلى هذا الصنف إلى حدوث خطأ من نوع Fatal.

الكتلة catch

يمكن استخدام كتل catch متعدّدة لالتقاط أصناف مختلفة من الاستثناءات. تستمر عملية تنفيذ الشيفرة الاعتيادية (في حال عدم رمي أي استثناء في الكتلة block) بعد آخر كتلة catch معرّفة في الشيفرة. يمكن رمي الاستثناءات (أو إعادة رميها) ضمن الكتلة catch.

لا تنفّذ الشيفرة التي تلي العبارة التي تسبّبت في رمي الاستثناء، وتحاول اللغة العثور على أول كتلة catch مطابقة. في حال عدم التقاط الاستثناء، تطلق اللغة خطأ من نوع PHP مع رسالة ‎‎"Uncaught Exception ..."‎ إلا إذا كان هناك متحكّم معرّف بواسطة الدالة set_exception_handler()‎.

في الإصدار 7.1 وما بعده من اللغة، يمكن لكتلة catch أن تحدّد استثناءات متعددة باستخدام الرمز (|). هذه الميزة مفيدة عندما تتعامل اللغة بالطريقة نفسها مع استثناءات مختلفة من تسلسلات هرمية لأصناف مختلفة.

الكتلة finally

في الإصدار 5.5 من اللغة يمكن استخدام الكتلة block بعد أو بدلًا من كتل catch. تُنفّذ الشيفرة الموجودة ضمن الكتلة finally دائمًا بعد الشيفرة الموجودة في كتل try و catch بغض النظر عمّا إذا كان هناك استثناء مرمي، و قبل العودة إلى عملية تنفيذ الشيفرة الاعتيادية.

ملاحظات

ملاحظة: تستخدم دوال PHP الداخلية بصورة عامة التبليغ عن الأخطاء، أما الاستثناءات فتستخدم من طرف الملحقات الحديثة كائنية التوجّه فقط. ولكن يمكن تحويل الأخطاء ببساطة إلى استثناءات باستخدام الصنف ErrorException.

نصيحة: تقدم مكتبة PHP القياسية (SPL) عددًا من الاستثناءات المدمجة المفيدة.

أمثلة

المثال 1: رمي استثناء

<?php
function inverse($x) {
    if (!$x) {
        throw new Exception('Division by zero.');
    }
    return 1/$x;
}

try {
    echo inverse(5) . "\n";
    echo inverse(0) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

// الاستمرار في عملية التنفيذ
echo "Hello World\n";
?>

يعطي المثال السابق المخرجات التالية:

0.2
Caught exception: Division by zero.
Hello World

المثال 2: التعامل مع الاستثناءات بواسطة كتلة finally

<?php
function inverse($x) {
    if (!$x) {
        throw new Exception('Division by zero.');
    }
    return 1/$x;
}

try {
    echo inverse(5) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
} finally {
    echo "First finally.\n";
}

try {
    echo inverse(0) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
} finally {
    echo "Second finally.\n";
}

// استمرار عملية التنفيذ
echo "Hello World\n";
?>

يعطي المثال السابق المخرجات التالية:

0.2
First finally.
Caught exception: Division by zero.
Second finally.
Hello World

المثال 3: استثناءات متداخلة

<?php

class MyException extends Exception { }

class Test {
    public function testing() {
        try {
            try {
                throw new MyException('foo!');
            } catch (MyException $e) {
                // رمي الاستثناء مرة أخرى
                throw $e;
            }
        } catch (Exception $e) {
            var_dump($e->getMessage());
        }
    }
}

$foo = new Test;
$foo->testing();

?>

يعطي المثال السابق المخرجات التالية:

string(4) "foo!"

المثال 4: كتل catch متعددة للتعامل مع الاستثناءات

<?php

class MyException extends Exception { }

class MyOtherException extends Exception { }

class Test {
    public function testing() {
        try {
            throw new MyException();
        } catch (MyException | MyOtherException $e) {
            var_dump(get_class($e));
        }
    }
}

$foo = new Test;
$foo->testing();

?>

يعطي المثال السابق المخرجات التالية:

string(11) "MyException"

توسيع الاستثناءات

يمكن تعريف صنف Exception خاص من قبل المستخدم وذلك بتوسيع الصنف Exception المُضمَّن في اللغة، وذلك لإنشاء استثناءات خاصة بالمستخدم.

مصادر