תפיסת Exceptions ב-PHP

כך תהפכו את הסקריפטים שלכם ב-PHP לעמידים וטובים יותר באמצעות ניהול שגיאות נבון.

לא מזמן, בעקבות מאמר אחר שבו כתבתי על cURL, כתבתי מאמר על try-catch ומיד חטפתי (שוב) קיתונות של רותחין (שוב) על למה לא פירטתי על Exceptions ב-PHP. אז אולי המאמר הזה הוא הזדמנות מצוינת לדבר קצת על Exceptions.

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

בואו ונדגים באמצעות דוגמה מ-php.net, אני אצור פונקציה שמה שהיא עושה זה להחזיר את המספר ההופכי – למשל אם אני דוחף לפונקציה 2, אני אקבל 1/2, אם אני אדחוף לפונקציה 3, אני אקבל 1/3 וכך הלאה.

וכך הפונקציה נראית:


<?php
function inverse($x) {
	return 1/$x;
}

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


<?php
function inverse($x) {
	return 1/$x;
}

inverse(0);

יניב לי אזהרת PHP לא סימפטית במיוחד:

שגיאת PHP המתקבלת כתוצאה מחילוק באפס
שגיאת PHP המתקבלת כתוצאה מחילוק באפס

המתכנת המתחיל בטח יגיד: 'אז מה?!? מי האידיוט שיכניס אפס לפונקציה הזו?' אבל זה בדיוק ההבדל בין תכנות סקלבילי ועמיד בפני בעיות ובין תכנות פריך שכל שינוי ונגיעה בו גורמים לקריסתו ולברדק אדיר.

המתכנת המנוסה יותר, יכניס תנאי שיבדוק את הקלט המתקבל ויחזיר משהו אחר אם הקלט בעייתי:


< ?php
function inverse($x) {
    if (!$x) {
        print 'Number is zero!!!! ahhhh!';
		return 'n/a';
    }
    else return 1/$x;
}

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

דרך ההתמודדות עם התקלה היא פרימיטיבית למדי – הדפסה היסטרית משהו של 'תקלה חמורה'. אבל, וזה אבל גדול, מדובר בדרך שמתאימה לאפליקציות קטנות בלבד. באפליקציה שבה יש יותר מכמה מאות שורות, דרך התמודדות כזו תהיה בעייתית. לא תמיד אנחנו יכולים להדפיס ולא תמיד אנחנו רוצים שהמשתמש יראה את התקלה. מה עושים? בדיוק בשביל זה יש Exceptions!

דרך השימוש היא פשוטה ביותר – שימו לב!


<?php
function inverse($x) {
    if (!$x) {
        throw new Exception('Division by zero.');
    }
    else return 1/$x;
}

inverse(0);

מה יקרה אם אני אריץ את הקוד הזה? ברגע שתתרחש התקלה ה-Exception יקפיץ fatal error וירשום את ההודעה שהגדרנו לו:

תקלת PHP שנובעת מ-Exception
תקלת PHP שנובעת מ-Exception

'רגע אחד!' חלק מכם בטח אומרים 'מה זה fatal error??? אז בשביל מה אני צריך את זה בכלל???' בדיוק בשביל זה יש את ה-try catch! אם אני מכניס את זה לתוך try-catch, אז אין לי fatal error אלא משהו אחר לגמרי – הנה דוגמה!


< ?php
function inverse($x) {
    if (!$x) {
        throw new Exception('Division by zero.');
    }
    else return 1/$x;
}

try {
    echo inverse(0) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

התוצאה המתקבלת:
Caught exception: Division by zero.

נחמד, לא?
במאמר על try-catch הזהרתי לא להשתמש במבנה הזה בלי הכרה, אפשר להנות מיתרונות ה-Excpetion בלי fatal error ובלי try-catch. איך עושים את זה? באמצעות הכרזה על פונקציה שמטפלת ב-exceptions ובכל פעם שנזרוק exception הפונקציה הזו תרוץ. למשל:


<?php
function customException($e) {
	echo 'Caught exception: ',  $e->getMessage(), "\n";
}
set_exception_handler('customException');

function inverse($x) {
    if (!$x) {
        throw new Exception('Division by zero.');
    }
    else return 1/$x;
}

 echo inverse(0);

יש עוד לא מעט בנושא Exceptions, אלו מכם שמתכנתים בגישה מונחית עצמים, ישמחו לדעת שיש class שלם של exceptions שאפשר לרשת ממנו ולעשות איתו דברים מופלאים – כמו להגדיר סוגים שונים של Exceptions – אבל זהו הבסיס. אם לא השתמשתם עד כה ב-exceptions, כדאי לחשוב איך להשתמש בו וליצור סקריפטים יציבים וחזקים יותר.

פוסטים נוספים שכדאי לקרוא

בינה מלאכותית

להריץ ממשק של open-webui על הרספברי פיי

להפעיל ממשק של צ׳אט ג׳יפיטי שאפשר לגשת אליו מכל מחשב ברשת הביתית על רספברי פיי עם מודל בשם tinydolphin שרץ על רספברי פיי.

תמונה של הבית הלבן עם מחשוב ענן וטקסט: FEDRAMP
פתרונות ומאמרים על פיתוח אינטרנט

FedRAMP & FIPS מבוא למתחילים

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

פיתוח ב-JavaScript

Axios interceptors

תכנון נכון של קריאות AJAX באפליקציה ריאקטית וניהול השגיאות או ההצלחות עם פיצ׳ר נחמד של axios

מיקרו בקרים

הפעלת מסך oled קטנטן עם esp32

יצירת מערכת מולטימדיה שלמה בגודל של בול דואר עם מיקרובקר ובעלות של דולרים בודדים. וגם על הדרך נלמד על ת׳רדים

ספריות ומודולים

מציאת PII באמצעות למידת מכונה

כך תגנו על משתמשים שלכם שמעלים מידע אישי רגיש כמו תעודות זהות באמצעות שירות אמאזוני.

גלילה לראש העמוד