Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

Try, Catch, Finally

جزء من قسم البرمجة كائنية التوجه في رحلة PHP على Coddy. الدرس 68 من 91.

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

ضع التعليمات البرمجية التي قد تُلقي استثناءً داخل كتلة try، ثم عالج الاستثناء في كتلة catch:

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

$calc = new Calculator();

try {
    echo $calc->divide(10, 0);
} catch (InvalidArgumentException $e) {
    echo "Error: " . $e->getMessage();
}

المخرجات:

Error: Cannot divide by zero

يمكنك التقاط أنواع مختلفة من الاستثناءات باستخدام كتل catch متعددة. يفحصها PHP بالترتيب، لذا ضع الاستثناءات الأكثر تحديدًا أولًا:

<?php
try {
    // كود محفوف بالمخاطر
} catch (InvalidArgumentException $e) {
    echo "Bad input: " . $e->getMessage();
} catch (Exception $e) {
    echo "Something went wrong: " . $e->getMessage();
}

يُنفَّذ الجزء finally بغضّ النظر عمّا إذا تم طرح استثناء أو التقاطه. وهو مثالي لمهام التنظيف مثل إغلاق الاتصالات:

<?php
try {
    echo "Attempting operation\n";
    throw new Exception("Failed");
} catch (Exception $e) {
    echo "Caught: " . $e->getMessage() . "\n";
} finally {
    echo "Cleanup complete";
}

المخرجات:

Attempting operation
Caught: Failed
Cleanup complete

يتم تنفيذ كتلة finally حتى إذا أرجعت قيمة من داخل كتلتي try أو catch، مما يجعلها موثوقة لعمليات التنظيف الأساسية.

challenge icon

التحدي

سهل

لنبنِ نظامًا لمعالجة file يوضّح كيفية عمل try-catch-finally معًا للتعامل مع errors بسلاسة، مع ضمان حدوث cleanup دائمًا.

ستنظّم كودك عبر ثلاثة files:

  • FileException.php: أنشئ فئة FileException مخصّصة تمتد من Exception. سيمثّل هذا errors المرتبطة بـ file في نظامك.
  • FileProcessor.php: أنشئ فئة FileProcessor تحاكي عمليات file. ضمّن file الخاص بـ FileException. يجب أن تحتوي فئتك على:
    • خاصية boolean خاصة $isOpen مهيّأة إلى false
    • طريقة open(string $filename): void تضبط $isOpen على true وتطبع "Opening: [filename]". إذا كان اسم file هو "invalid.txt"، فألقِ FileException مع الرسالة "Cannot open file"
    • طريقة process(): void تطبع "Processing file...". إذا كانت قيمة $isOpen هي false، فألقِ RuntimeException مع الرسالة "File not open"
    • طريقة close(): void تضبط $isOpen على false وتطبع "File closed"
    • طريقة isOpen(): bool تُرجع الحالة current
  • main.php: ضمّن file الخاص بـ FileProcessor. ستتلقى input واحدًا: اسم file.

    أنشئ FileProcessor واستخدم بنية try-catch-finally من أجل:

    • في كتلة try: استدعِ open() باستخدام اسم file، ثم استدعِ process()
    • التقط FileException أولًا واطبع "File error: [message]"
    • التقط RuntimeException واطبع "Runtime error: [message]"
    • في كتلة finally: تحقّق مما إذا كان file مفتوحًا باستخدام isOpen()، وإذا كان كذلك، فاستدعِ close(). ثم اطبع "Cleanup complete"

تضمن كتلة finally حدوث cleanup سواء نجحت العمليات أم فشلت. يُعد هذا النمط أساسيًا لإدارة الموارد مثل files واتصالات قواعد البيانات أو مقابس الشبكة، حيث يجب إجراء cleanup بغضّ النظر عمّا يحدث أثناء المعالجة.

جرّب بنفسك

<?php
require_once 'FileProcessor.php';

// اقرأ الإدخال
$filename = trim(fgets(STDIN));

// TODO: أنشئ مثيلاً من FileProcessor

// TODO: استخدم بنية try-catch-finally:
// - في كتلة try: استدعِ open() مع filename، ثم استدعِ process()
// - التقط FileException أولاً واطبع "File error: [message]"
// - التقط RuntimeException واطبع "Runtime error: [message]"
// - في كتلة finally: تحقق مما إذا كان الملف مفتوحاً باستخدام isOpen()، وإذا كان كذلك استدعِ close()
//   Then print "Cleanup complete"

?>
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم PHP عبر الإنترنت