0Pricing
PHP Academy · درس

Try وCatch وFinally

تعاملوا مع الاستثناءات وقت التشغيل بسلاسة باستخدام كتل try/catch/finally

Try وCatch وFinally درس مجاني في PHP Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في PHP Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة PHP Academy 4 دروس في المجموع.

الاستثناءات مقابل الأخطاء

لدى PHP طريقتان للإشارة إلى المشكلات:

  • الأخطاء — الإشعارات والتحذيرات والأخطاء الفادحة التقليدية في PHP (نوقشت في الدرس السابق)
  • الاستثناءات — كائنات تُطرح عند حدوث أمر استثنائي؛ ويتم التعامل معها باستخدام try/catch

الاستثناءات هي النهج الحديث والمفضّل لمعالجة الأخطاء القابلة للاسترداد.

طرح استثناء

استخدم throw للإشارة إلى حدوث خطأ ما:

<?php
function divide(float $a, float $b): float {
    if ($b == 0) {
        throw new InvalidArgumentException('Cannot divide by zero');
    }
    return $a / $b;
}

echo divide(10, 2);   // 5
// divide(10, 0);     // throws exception

كتلة try / catch

ضع الكود الذي قد يطرح استثناءً داخل try، وتعامل مع الاستثناءات داخل catch:

<?php
try {
    $result = divide(10, 0);
    echo $result;
} catch (InvalidArgumentException $e) {
    echo 'Error: ' . $e->getMessage();
    echo ' in ' . $e->getFile() . ':' . $e->getLine();
}

كتل catch متعددة

تعامل مع أنواع الاستثناءات المختلفة في كتل catch منفصلة:

<?php
try {
    $pdo = new PDO($dsn, $user, $pass);
    $result = performQuery($pdo);
} catch (PDOException $e) {
    error_log('DB error: ' . $e->getMessage());
    echo 'Database unavailable';
} catch (RuntimeException $e) {
    echo 'Runtime error: ' . $e->getMessage();
} catch (\Throwable $e) {
    echo 'Unexpected error: ' . $e->getMessage();
}

كتلة finally

يُنفّذ finally بغض النظر عن طرح استثناء من عدمه — ولذلك فهو مثالي للتنظيف:

<?php
$connection = null;
try {
    $connection = openDatabaseConnection();
    $data = fetchData($connection);
} catch (DatabaseException $e) {
    error_log($e->getMessage());
    echo 'DB error';
} finally {
    // Always runs — even if exception was thrown
    if ($connection) {
        closeConnection($connection);
    }
}

تسلسل الاستثناءات الهرمي

التسلسل الهرمي لفئات الاستثناءات في PHP:

  • Throwable (واجهة)
  • ├─ Error — أخطاء محرّك PHP (TypeError، وParseError…)
  • └─ Exception — استثناءات التطبيق
  • ├─ RuntimeException
  • ├─ InvalidArgumentException
  • ├─ LogicException
  • └─ PDOException

التعامل مع Throwable

تعامل مع كل من الاستثناءات وأخطاء PHP باستخدام Throwable:

<?php
try {
    $result = someFunction();
} catch (\Exception $e) {
    echo 'Exception: ' . $e->getMessage();
} catch (\Error $e) {
    echo 'PHP Error: ' . $e->getMessage();
}

// Or catch both at once:
try {
    // ...
} catch (\Throwable $e) {
    echo get_class($e) . ': ' . $e->getMessage();
}

catch موحّد (PHP 8)

تسمح PHP 8 بالتعامل مع أنواع استثناءات متعددة داخل كتلة catch واحدة:

<?php
try {
    processRequest();
} catch (InvalidArgumentException | RuntimeException $e) {
    echo 'Handled: ' . $e->getMessage();
}

// Compare PHP 7 approach:
// catch (InvalidArgumentException $e) { ... }
// catch (RuntimeException $e) { ... }

إعادة طرح الاستثناءات

التقط الاستثناء وسجّله ثم أعد طرحه لتمريره إلى أعلى مكدس الاستدعاءات:

<?php
function processOrder(int $id): void {
    try {
        $order = loadOrder($id);
        $order->process();
    } catch (PaymentException $e) {
        error_log('Payment failed for order ' . $id . ': ' . $e->getMessage());
        throw $e;  // re-throw after logging
    }
}

تسلسل الاستثناءات

مرّر الاستثناء الأصلي باعتباره «السابق» للحفاظ على السياق:

<?php
try {
    $data = fetchFromAPI();
} catch (NetworkException $e) {
    throw new ServiceUnavailableException(
        'Cannot reach upstream service',
        0,
        $e  // $previous — preserves original cause
    );
}

// Retrieve original:
// $e->getPrevious()

set_exception_handler

سجّل معالجًا عامًا للاستثناءات غير المُعالجة:

<?php
set_exception_handler(function(\Throwable $e): void {
    error_log(sprintf(
        '[UNCAUGHT] %s: %s in %s:%d',
        get_class($e),
        $e->getMessage(),
        $e->getFile(),
        $e->getLine()
    ));
    http_response_code(500);
    echo 'An unexpected error occurred. Please try again.';
    exit(1);
});

تحقق سريع

أي كتلة ضمن try/catch/finally مضمونة التنفيذ بغض النظر عن طرح استثناء من عدمه؟

مراجعة: try/catch/finally

ملخص معالجة الاستثناءات:

  • اطرح الاستثناءات باستخدام throw new ExceptionClass()
  • تعامل معها باستخدام catch (Type $e)
  • استخدم كتل catch متعددة للأنواع المختلفة
  • يُنفّذ finally دائمًا — استخدمه للتنظيف
  • catch الموحّد في PHP 8: catch (A | B $e)
  • أعد الطرح للحفاظ على سياق مكدس الاستدعاءات

الأسئلة الشائعة

هل درس «Try وCatch وFinally» مجاني؟

نعم — نص درس «Try وCatch وFinally» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة PHP Academy، انتقل إلى CoddyKit PRO. تتضمن دورة PHP Academy 4 دروس في المجموع.

ماذا ستتعلم في «Try وCatch وFinally»؟

تعاملوا مع الاستثناءات وقت التشغيل بسلاسة باستخدام كتل try/catch/finally تتمرن على PHP Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ PHP Academy؟

لا تُشترط خبرة سابقة. PHP Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «Try وCatch وFinally»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس PHP Academy هذا؟

نعم. كل درس في PHP Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. أنواع أخطاء PHP وإعدادات الإبلاغ عنها
  2. Try وCatch وFinally
  3. إنشاء استثناءات مخصّصة
  4. تسجيل الأخطاء وأفضل الممارسات
← العودة إلى PHP Academy