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

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

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

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

عندما تطرح استثناءً، فإنك تنشئ مثيلًا من الفئة 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);

سيؤدي ذلك إلى ظهور خطأ استثناء غير مُعالج مع الرسالة "Insufficient funds".

يوفّر 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;
    }
}

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

challenge icon

التحدي

سهل

لنَبْنِ نظامًا لإدارة المخزون يستخدم فئات الاستثناءات المضمّنة في PHP للإشارة إلى أنواع مختلفة من المشكلات. ستنشئ مخزونًا للمنتجات حيث يمكن أن تفشل العمليات بطرق محددة وذات معنى.

ستنظّم الشيفرة عبر ثلاثة ملفات:

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

    أنشئ Inventory وأضف Product جديدًا باستخدام SKU والاسم المعطيين، وinitial quantity تساوي 10.

    استنادًا إلى operation:

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

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

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

جرّب بنفسك

<?php

require_once 'Inventory.php';

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

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

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

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

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

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