Menu
Coddy logo textTech

Try, Catch, Finally

חלק מהיחידה תכנות מונחה עצמים במסלול ה-PHP של Coddy. שיעור 68 מתוך 91.

עכשיו, כשאתה יודע איך ליצור ולזרוק חריגות, עליך ללמוד איך לתפוס אותן. המבנה 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

אתגר

קל

בואו נבנה מערכת לעיבוד קבצים שמדגימה כיצד try-catch-finally פועלים יחד כדי לטפל בשגיאות בצורה מסודרת, תוך הבטחה שניקוי המשאבים יתבצע תמיד.

תארגנו את הקוד שלכם בשלושה קבצים:

  • FileException.php: צרו מחלקה מותאמת אישית בשם FileException שמרחיבה את Exception. היא תייצג שגיאות הקשורות לקבצים במערכת שלכם.
  • FileProcessor.php: צרו מחלקה בשם FileProcessor שמדמה פעולות על קבצים. כללו את הקובץ FileException. למחלקה שלכם צריכים להיות:
    • מאפיין בוליאני פרטי $isOpen שמאותחל לערך false
    • מתודה open(string $filename): void שמגדירה את $isOpen לערך true ומדפיסה "Opening: [filename]". אם שם הקובץ הוא "invalid.txt", זרקו FileException עם ההודעה "Cannot open file"
    • מתודה process(): void שמדפיסה "Processing file...". אם הערך של $isOpen הוא false, זרקו RuntimeException עם ההודעה "File not open"
    • מתודה close(): void שמגדירה את $isOpen לערך false ומדפיסה "File closed"
    • מתודה isOpen(): bool שמחזירה את המצב הנוכחי
  • main.php: כללו את הקובץ FileProcessor. תקבלו קלט אחד: שם קובץ.

    צרו מופע של FileProcessor והשתמשו במבנה try-catch-finally כדי:

    • בבלוק try: קראו ל־open() עם שם הקובץ, ואז קראו ל־process()
    • תפסו תחילה את FileException והדפיסו "File error: [message]"
    • תפסו את RuntimeException והדפיסו "Runtime error: [message]"
    • בבלוק finally: בדקו אם הקובץ פתוח באמצעות isOpen(), ואם כן, קראו ל־close(). לאחר מכן הדפיסו "Cleanup complete"

בלוק finally מבטיח שניקוי המשאבים יתבצע בין אם הפעולות מצליחות ובין אם הן נכשלות. תבנית זו חיונית לניהול משאבים כמו קבצים, חיבורי מסד נתונים או שקעי רשת, שבהם יש לבצע ניקוי ללא קשר למה שמתרחש במהלך העיבוד.

נסו בעצמכם

<?php
require_once 'FileProcessor.php';

// קרא את הקלט
$filename = trim(fgets(STDIN));

// TODO: צור מופע של FileProcessor

// TODO: השתמש במבנה try-catch-finally:
// - בבלוק try: קרא ל־open() עם שם הקובץ, ואז קרא ל־process()
// - תפוס תחילה את FileException והדפס "File error: [message]"
// - תפוס את RuntimeException והדפס "Runtime error: [message]"
// - בבלוק finally: בדוק באמצעות isOpen() אם הקובץ פתוח, ואם כן קרא ל־close()
//   לאחר מכן הדפס "Cleanup complete"

?>
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר PHP אונליין