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، مما يجعلها موثوقة لعمليات التنظيف الأساسية.
التحدي
سهللنبنِ نظامًا لمعالجة 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
- خاصية boolean خاصة
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"
?>يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات OOP
الملفات الخارجيةمقدمة في OOPClasses مقابل Objectsالكلمة المفتاحية $thisالـ Methodsالـ Propertiesالمنشئ (__construct)الهادم (__destruct)مراجعة - آلة حاسبة بسيطة4الوراثة
الوراثة الأساسيةالكلمة المفتاحية parent::إعادة تعريف الدوال (Method Overriding)الكلمة المفتاحية finalالأصناف المجردة (Abstract Classes)مراجعة - هيكلية الموظفين7التغليف (Encapsulation)
العام، المحمي، الخاص (Public, Protected, Private)نظرة متعمقة على معدلات الوصولدوال Getters و Settersإخفاء المعلوماتميزة Constructor Promotion (8.0)مراجعة - نظام سجلات الطلاب10مفاهيم البرمجة كائنية التوجه المتقدمة
التركيب مقابل الوراثةحقن التبعيةالأصناف المجهولةالتعدادات (PHP 8.1)الألياف (PHP 8.1)تعمق في استنساخ الكائناتالمولدات والمكررات13أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط طريقة القالبنمط الحالةنمط التركيبنمط المستودع2مساحات الأسماء والتحميل التلقائي
مقدمة إلى مساحات الأسماءالكلمة المفتاحية useمعيار التحميل التلقائي PSR-4أداة التحميل التلقائي Composerملخص - مشروع منظم5الواجهات والعقود
مقدمة إلى الواجهاتتنفيذ الواجهاتتنفيذ واجهات متعددةالواجهة مقابل الـ Abstract Classالـ Type Hinting مع الواجهاتملخص - حاسبة الأشكال8الميثودات السحرية (Magic Methods)
مقدمة في الميثودات السحرية__toString و __debugInfo__get, __set, __isset, __unset__call و __callStatic__clone واستنساخ الكائنات__serialize و __unserializeمراجعة - Custom Collection11نظام الأنواع ومعالجة الأخطاء
تصريحات الأنواعالأنواع القابلة للقيمة Nullأنواع الاتحاد والتقاطعفئات الاستثناءاتتسلسل الاستثناءات المخصصةTry, Catch, Finallyمراجعة - مدقق النماذج3خصائص الكلاس
خصائص الـ Instance مقابل الخصائص الساكنة (Static)الثوابت في الكلاساتالدوال والخصائص الساكنة (Static)الخصائص الخاصة (Private) والمحمية (Protected)خصائص للقراءة فقط (Readonly) في PHP 8.1مراجعة - مدير الحساب البنكي6تعدد الأشكال (Polymorphism)
مراجعة إعادة تعريف الدوال (Method Overriding)تعدد الأشكال عبر الـ Interfacesتلميح النوع (Type Hinting) وأنواع الاتحاد (Union Types)الربط الاستاتيكي المتأخر (Late Static Binding)ملخص - معالج الدفع (Payment Processor)تدرّب بنفسك: مترجم PHP عبر الإنترنت