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

فئات الاستثناءات

جزء من قسم Object Oriented Programming في رحلة PHP على Coddy — الدرس 66 من 91.

في PHP، الاستثناءات (exceptions) هي كائنات تُستخدم للإشارة إلى حدوث خطأ ما أثناء التنفيذ. الفئة الأساسية لجميع الاستثناءات هي Exception، وفهم هيكلها يساعدك على التعامل مع الأخطاء بفعالية في تطبيقات البرمجة كائنية التوجه (OOP).

عندما تقوم بطرح استثناء (exception)، فإنك تنشئ مثيلاً من الفئة Exception (أو فئة فرعية منها) مع رسالة تصف الخطأ الذي حدث:

<?php
class BankAccount {
    public function __construct(private float $balance = 0) {}
    
    public function withdraw(float $amount): float {
        if ($amount > $this->balance) {
            throw new Exception("Insufficient funds");
        }
        $this->balance -= $amount;
        return $amount;
    }
}

$account = new BankAccount(100);
$account->withdraw(150);

سيؤدي هذا إلى حدوث خطأ استثناء غير ملتقط (uncaught exception error) مع الرسالة "Insufficient funds".

يوفر PHP العديد من فئات الاستثناءات (exception classes) المدمجة لمواقف مختلفة. تشير InvalidArgumentException إلى مدخلات غير صالحة، وتشير RuntimeException إلى أخطاء أثناء التنفيذ، وتمثل LogicException أخطاء برمجية:

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

يحمل كل كائن استثناء معلومات مفيدة: getMessage() تُرجع رسالة الخطأ، و getCode() تُرجع رمز خطأ اختياري، و getFile() و getLine() يخبرانك بمكان إلقاء الاستثناء. استخدام أنواع استثناءات محددة يجعل غرض الكود الخاص بك أكثر وضوحاً ويسمح بمعالجة أخطاء أكثر دقة.

challenge icon

التحدي

سهل

لنقم ببناء نظام إدارة مخزون يستخدم فئات الاستثناءات (exceptions) المدمجة في PHP للإشارة إلى أنواع مختلفة من المشكلات. ستقوم بإنشاء مخزون منتجات حيث يمكن أن تفشل العمليات بطرق محددة وذات مغزى.

ستقوم بتنظيم الكود الخاص بك عبر ثلاثة ملفات:

  • Product.php — أنشئ فئة Product تمثل عنصراً في المخزون. استخدم خاصية constructor promotion لتعريف $sku (string) عام، و $name (string) عام، و $quantity (int) خاص. يجب أن تحتوي الفئة على:

    • طريقة getQuantity(): int تعيد الكمية الحالية
    • طريقة addStock(int $amount): void تزيد الكمية. إذا كان المبلغ أقل من 1، قم برمي InvalidArgumentException مع الرسالة "Amount must be positive"
    • طريقة removeStock(int $amount): void تنقص الكمية. إذا كان المبلغ أقل من 1، قم برمي InvalidArgumentException مع الرسالة "Amount must be positive". إذا تجاوز المبلغ الكمية الحالية، قم برمي RuntimeException مع الرسالة "Insufficient stock"
  • Inventory.php — أنشئ فئة Inventory تدير مجموعة من المنتجات. قم بتضمين ملف Product. يجب أن تحتوي الفئة على:
    • مصفوفة خاصة لتخزين المنتجات مفهرسة بواسطة SKU
    • طريقة addProduct(Product $product): void تضيف منتجاً. إذا كان هناك منتج بنفس SKU موجوداً بالفعل، قم برمي LogicException مع الرسالة "Product already exists: [sku]"
    • طريقة getProduct(string $sku): Product تعيد منتجاً بواسطة SKU. إذا لم يتم العثور عليه، قم برمي InvalidArgumentException مع الرسالة "Product not found: [sku]"
  • main.php — قم بتضمين ملف Inventory. ستتلقى ثلاثة مدخلات: SKU، واسم المنتج، وعملية ("add"، أو "remove"، أو "duplicate").

    أنشئ Inventory وأضف Product جديداً باستخدام SKU والاسم المعطيين، وبكمية أولية قدرها 10.

    بناءً على العملية:

    • "add": استدعِ addStock(5) على المنتج، ثم اطبع "Stock updated: [quantity]"
    • "remove": استدعِ removeStock(15) على المنتج (هذا يجب أن يرمي استثناءً)
    • "duplicate": حاول إضافة منتج آخر بنفس SKU (هذا يجب أن يرمي استثناءً)

    عند رمي استثناء، اطبع اسم فئة الاستثناء متبوعاً بـ ": " ورسالة الاستثناء. استخدم دالة get_class() في PHP للحصول على اسم الفئة.

يوضح هذا التحدي كيف تتواصل أنواع الاستثناءات المختلفة مع أنواع مختلفة من المشكلات — المدخلات غير الصالحة، وفشل وقت التشغيل، وأخطاء المنطق — مما يجعل معالجة الأخطاء في الكود الخاص بك أكثر دقة وفائدة.

ورقة مرجعية

في لغة PHP، الاستثناءات (Exceptions) هي كائنات تشير إلى حدوث أخطاء أثناء التنفيذ. الفئة الأساسية هي Exception.

لرمي استثناء، قم بإنشاء مثيل مع رسالة وصفية:

<?php
class BankAccount {
    public function __construct(private float $balance = 0) {}
    
    public function withdraw(float $amount): float {
        if ($amount > $this->balance) {
            throw new Exception("Insufficient funds");
        }
        $this->balance -= $amount;
        return $amount;
    }
}

توفر PHP فئات استثناءات مدمجة لمواقف مختلفة:

  • InvalidArgumentException — تشير إلى مدخلات غير صالحة
  • RuntimeException — تشير إلى أخطاء أثناء التنفيذ
  • LogicException — تمثل أخطاء برمجية
<?php
class Calculator {
    public function divide(int $a, int $b): float {
        if ($b === 0) {
            throw new InvalidArgumentException("Cannot divide by zero");
        }
        return $a / $b;
    }
}

توفر كائنات الاستثناء طرقاً (methods) مفيدة:

  • getMessage() — تعيد رسالة الخطأ
  • getCode() — تعيد رمز خطأ اختياري
  • getFile() — تعيد الملف الذي تم رمي الاستثناء فيه
  • getLine() — تعيد رقم السطر الذي تم رمي الاستثناء فيه

استخدم get_class() لاسترداد اسم الفئة لكائن الاستثناء.

جرّب بنفسك

<?php

require_once 'Inventory.php';

// قراءة المدخلات
$sku = trim(fgets(STDIN));
$name = trim(fgets(STDIN));
$operation = trim(fgets(STDIN));

try {
    // TODO: إنشاء مخزون (Inventory)
    // TODO: إنشاء منتج (Product) باستخدام SKU والاسم المعطيين وكمية أولية قدرها 10
    // TODO: إضافة المنتج إلى المخزون
    
    // TODO: بناءً على العملية:
    // - "add": استدعاء addStock(5) للمنتج، ثم طباعة "Stock updated: [quantity]"
    // - "remove": استدعاء removeStock(15) للمنتج
    // - "duplicate": محاولة إضافة منتج آخر بنفس الـ SKU
    
} catch (Exception $e) {
    // TODO: طباعة اسم فئة الاستثناء متبوعاً بـ ": " والرسالة
    // تلميح: استخدم get_class($e) للحصول على اسم الفئة
}

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

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

جميع دروس Object Oriented Programming