היררכיית חריגות מותאמת אישית
חלק מהיחידה תכנות מונחה עצמים במסלול ה-PHP של Coddy. שיעור 67 מתוך 91.
בעוד שמחלקות החריגות המובנות של PHP מכסות תרחישים נפוצים, יישומים אמיתיים זקוקים לעיתים קרובות לסוגי שגיאות ספציפיים יותר. יצירת היררכיית חריגות מותאמת אישית מאפשרת לך להגדיר חריגות שמתאימות לתחום שלך וללכוד אותן ברמות שונות של ספציפיות.
כדי ליצור חריגה מותאמת אישית, פשוט יש לרשת את המחלקה Exception או אחת ממחלקות המשנה שלה:
<?php
class PaymentException extends Exception {}
class InsufficientFundsException extends PaymentException {
public function __construct(
private float $required,
private float $available
) {
parent::__construct("Need $required but only $available available");
}
public function getShortfall(): float {
return $this->required - $this->available;
}
}
שימו לב ש־InsufficientFundsException יורשת מ־PaymentException, ולא ישירות מ־Exception. כך נוצרת היררכיה שמאפשרת לכם ללכוד את כל החריגות הקשורות לתשלום באמצעות בלוק catch אחד, או לטפל בכל אחת מהן בנפרד.
חריגות מותאמות אישית יכולות לכלול מאפיינים ומתודות נוספים הרלוונטיים לשגיאה. כאן, getShortfall() מספקת מידע שימושי שחריגה כללית לא יכלה לספק:
<?php
class Wallet {
public function __construct(private float $balance) {}
public function pay(float $amount): void {
if ($amount > $this->balance) {
throw new InsufficientFundsException($amount, $this->balance);
}
$this->balance -= $amount;
}
}
היררכיית חריגות שתוכננה היטב הופכת את הקוד שלך לקל יותר לתחזוקה. בעת טיפול בחריגות, אפשר לבחור טיפול כללי או ספציפי ככל שנדרש, ואובייקטי החריגות עצמם כוללים הקשר משמעותי לגבי מה השתבש.
אתגר
קלבואו נבנה מערכת לעיבוד הזמנות עם היררכיית חריגות מותאמת אישית שמטפלת בסוגים שונים של כשלים בהזמנות. תיצרו חריגות שנושאות מידע שימושי על מה שהשתבש, וכך הטיפול בשגיאות יהיה מדויק ומפורט יותר.
תארגנו את הקוד בארבעה קבצים:
OrderException.php: צרו מחלקת בסיס בשםOrderExceptionשמרחיבה אתException. היא תשמש כמחלקת האב לכל החריגות הקשורות להזמנות, ותאפשר לכם לתפוס כל בעיה בהזמנה באמצעות בלוק catch יחיד כשיידרש.OutOfStockException.php: צרו מחלקה בשםOutOfStockExceptionשמרחיבה אתOrderException. החריגה הזאת צריכה לקבל בבנאי שם של מוצר ואת הכמות המבוקשת. השתמשו בקידום מאפיינים בבנאי עבור המאפיינים הפרטיים האלה. קראו לבנאי של מחלקת האב עם הודעה בתבנית"[productName] is out of stock (requested: [quantity])". הוסיפו מתודהgetProductName(): stringשמחזירה את שם המוצר.InvalidQuantityException.php: צרו מחלקה בשםInvalidQuantityExceptionשמרחיבה אתOrderException. החריגה הזאת צריכה לקבל בבנאי ערך של כמות, תוך שימוש בקידום מאפיינים כמאפיין פרטי. קראו לבנאי של מחלקת האב עם ההודעה"Invalid quantity: [quantity]". הוסיפו מתודהgetQuantity(): intשמחזירה את ערך הכמות.main.php: כללו את שלושת קובצי החריגות. תקבלו שתי קלטים: שם מוצר וכמות (כמחרוזת שיש להמיר למספר שלם).בהתאם לערך הכמות, זרקו את החריגה המתאימה:
- אם הכמות קטנה מ־1, זרקו
InvalidQuantityException - אם הכמות גדולה מ־100, זרקו
OutOfStockException(כדי לדמות מלאי לא מספיק) - אחרת, הדפיסו
"Order placed: [quantity]x [productName]"
תפסו חריגות באמצעות ההיררכיה. תחילה תפסו את
InvalidQuantityExceptionוהדפיסו"Quantity error: [message] (value: [quantity])"באמצעות הודעת החריגה והמתודהgetQuantity(). לאחר מכן תפסו אתOutOfStockExceptionוהדפיסו"Stock error: [message] (product: [productName])"באמצעות הודעת החריגה והמתודהgetProductName().- אם הכמות קטנה מ־1, זרקו
ההיררכיה הזאת מאפשרת לכם לטפל בחריגות ספציפיות בנפרד, ובו בזמן לשמור על האפשרות לתפוס את כל הבעיות הקשורות להזמנות באמצעות מחלקת הבסיס OrderException. המתודות המותאמות אישית בכל חריגה מספקות מידע הקשרי שחריגה כללית לא הייתה יכולה לספק.
נסו בעצמכם
<?php
// כלול את כל קובצי החריגות
require_once 'OrderException.php';
require_once 'OutOfStockException.php';
require_once 'InvalidQuantityException.php';
// קרא את הקלט
$productName = trim(fgets(STDIN));
$quantity = intval(trim(fgets(STDIN)));
// TODO: השתמש ב־try-catch כדי לטפל בעיבוד ההזמנה
// בתוך בלוק try:
// - אם quantity < 1, זרוק InvalidQuantityException
// - אם quantity > 100, זרוק OutOfStockException
// - אחרת, הדפס "Order placed: [quantity]x [productName]"
//
// תפוס תחילה את InvalidQuantityException:
// - הדפס "Quantity error: [message] (value: [quantity])" באמצעות getMessage() ו־getQuantity()
//
// תפוס את OutOfStockException:
// - הדפס "Stock error: [message] (product: [productName])" באמצעות getMessage() ו־getProductName()
?>השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים (OOP)
קבצים חיצונייםמבוא ל-OOPמחלקות לעומת אובייקטיםמילת המפתח $thisמתודותמאפייניםבנאי (__construct)הורס (__destruct)חזרה: מחשבון פשוט4ירושה
ירושה בסיסיתמילת המפתח parent::דריסת מתודותמילת המפתח finalמחלקות מופשטותסיכום – היררכיית עובדים7כימוס
ציבורי, מוגן, פרטימפרטי גישה לעומקמתודות גישה ועדכוןהסתרת מידעקידום פרמטרים בבנאי (8.0)סיכום – מערכת רישומי תלמידים2מרחבי שמות וטעינה אוטומטית
מבוא למרחבי שמותמילת המפתח useתקן הטעינה האוטומטית PSR-4הטוען האוטומטי של Composerסיכום – פרויקט מאורגן5ממשקים וחוזים
מבוא לממשקיםמימוש ממשקיםמימוש של כמה ממשקיםממשק לעומת מחלקה מופשטתרמזי טיפוסים עם ממשקיםסיכום - מחשבון צורות8מתודות קסם
מבוא למתודות קסם__toString ו־__debugInfo__get, __set, __isset, __unset__call ו־__callStatic__clone ושיבוט אובייקטים__serialize ו־__unserializeסיכום – אוסף מותאם אישית11מערכת טיפוסים וטיפול בשגיאות
הצהרות טיפוסיםטיפוסים שניתנים להכלה של nullטיפוסי איחוד וחיתוךמחלקות חריגההיררכיית חריגות מותאמת אישיתTry, Catch, Finallyסיכום – מאמת טפסים3מאפייני מחלקה
מאפייני מופע לעומת מאפיינים סטטייםקבועים במחלקותמתודות ומאפיינים סטטייםמאפיינים פרטיים ומוגניםמאפיינים לקריאה בלבד (PHP 8.1)סיכום – מנהל חשבון בנק6פולימורפיזם
בחינה מחדש של דריסת מתודותפולימורפיזם באמצעות ממשקיםרמזי טיפוסים וטיפוסי איחודקישור סטטי מאוחרסיכום — מעבד תשלומיםתרגלו בעצמכם: קומפיילר PHP אונליין