נגישות       נגישות
שינוי גודל טקסט:
א א א
שינוי צבעי האתר:
? מקשי קיצור:

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

הפעלת מקשי הקיצור תלויה בדפדפן שבו אתם משתמשים.

Internet Explorer, Chrome ובגרסאות ישנות של Firefox: לחצו על מקש Alt ועל מקש המספר או האות על-פי הרשימה. ב Firefox 3 ומעלה: לחצו על המקשים Alt + Shift + המספר או האות.

S - עבור לתוכן הדף
L - חיפוש
1- עמוד הבית
2 - פרוייקטים
3 - מדריכים
4 - אודות
5 - צרו קשר
6 - הצהרת נגישות
 

טיפול ב-exceptions ב-PHP

מחבר:
בתאריך:

 

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

ראשית, בוא נראה מה עלול לקרות אם מנסים לחלק באפס ללא טיפול ב-exceptions.

בתוך המערך targilim$ מקוננים מערכים נוספים שכוללים כל אחד שני מספרים. המערך רץ דרך לולאה שיוצרת אובייקטים של המחלקה Calculate, ובתוכה המתודה divide מספקת את התוצאה של חלוקת המספר הראשון בשני.

class Calculate
{
  private $num1;
  private $num2;
 
  public function __construct($num1,$num2){
    $this -> num1 = (int)$num1;
    $this -> num2 = (int)$num2;
  }
 
  public function divide(){
    return $this -> num1 / $this -> num2;
  }
}
 

$targilim = array(
    array(8,1),
    array(9,0),
    array(4,2),
    array(6,1)
 );
 
foreach($targilim as $targil => $value){
  $calculate = new Calculate($value[0],$value[1]);
  echo $calculate -> divide();
  echo "<hr />";
}

התוצאה של התרגיל, מראה מה עלולה להיות התגובה של PHP לשגיאה בקוד, דוגמת חלוקה באפס.

הודעת שגיאה של PHP לדוגמה

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

 

eBook cover The essentials of Object Oriented PHP

 

כיצד לזרוק Exception?

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

class Calculate
{
  private $num1;
  private $num2;
 
  public function __construct($num1,$num2){
    $this -> num1 = (int)$num1;
    $this -> num2 = (int)$num2;
  }
 
  public function divide(){
    if($this -> num2 === 0 ){
      throw new Exception("Error! trying to divide by zero.");
    }
 
    return $this -> num1 / $this -> num2;
  }
}

 

קליטת ה-exception וטיפול ב-exception

אם רק נזרוק exception, לא נמנע את השגיאה. כדי למנוע את השגיאה, נחלק את הקוד לשני בלוקים. בלוק אחד שיריץ את הקוד הנורמלי נטול השגיאות והחריגים, ובלוק שני שיקלוט את השגיאות והחריגים ויטפל בהם. הבלוק שיריץ את הקוד הרגיל הוא בלוק try, והבלוק שיתפוס ויטפל בשגיאות ובחריגים הוא בלוק catch, שמשתמש במתודות של המחלקה Exception, שהיא מחלקה מובנה לטיפול בחריגים שמספק PHP. בדוגמה זו, הודעת השגיאה שזרקנו מוצגת על ידי המתודה getMessage(), שמספקת המחלקה Exception בתוך בלוק catch.

try{
  $calculate = new Calculate($value[0],$value[1]);
  echo $calculate -> divide();
  echo "<hr />";
} catch (Exception $e){
  echo "Message: " . $e -> getMessage() . "<br />";
  echo "<hr />";
}

זה הקוד המלא:

class Calculate
{
  private $num1;
  private $num2;
 
  public function __construct($num1,$num2){
    $this -> num1 = (int)$num1;
    $this -> num2 = (int)$num2;
  }
 
  public function divide(){
    if($this -> num2 === 0 ){
      throw new Exception("Error! trying to divide by zero.");
    }
 
    return $this -> num1 / $this -> num2;
  }
}
 
$targilim = array(
    array(8,1),
    array(9,0),
    array(4,2),
    array(6,1)
 );
 
foreach($targilim as $targil => $value){
 
  try{
    $calculate = new Calculate($value[0],$value[1]);
    echo $calculate -> divide();
    echo "<hr />";
 
  } catch (Exception $e){
    echo "Message: " . $e -> getMessage() . "<br />";
    echo "<hr />";
  }
}

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

דוגמה לשימוש ב-class exception של PHP

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

מתודות מועילות נוספות שמספקת המחלקה Exception הן:

getFile() שמציינת את נתיב הקובץ שבו התרחשה השגיאה.

getLine() שמראה את השורה בקובץ שבו התרחשה השגיאה.

אם נרצה להוסיף את המידע הזה להודעת השגיאה שמספק לנו הטיפול ב- Exception, אנו יכולים לעשות זאת באמצעות הקוד הבא:

try{
  $calculate = new Calculate($value[0],$value[1]);
  echo $calculate -> divide();
  echo "<hr />";
} catch (Exception $e){
  echo "Message: " . $e -> getMessage() . "<br />";
  echo "File: " . $e -> getFile() . "<br />";
  echo "Line: " . $e -> getLine() . "<br />";
  echo "<hr />";
}

תוצאה לדוגמה:

המתודות השונות שמספק exception של PHP

 

כתיבת exception לקובץ log

במקרים שבהם נרצה לכתוב מידע על השגיאה לקובץ לוג ניתן לעשות זאת באמצעות הפקודה error_log(). לדוגמה:

error_log($e -> getMessage());

זה הקוד המלא שאותו כתבנו במדריך עד כה:

class Calculate
{
  private $num1;
  private $num2;
 
  public function __construct($num1,$num2){
    $this -> num1 = (int)$num1;
    $this -> num2 = (int)$num2;
  }
 
  public function divide(){
    if($this -> num2 === 0 ){
      throw new Exception("Error! trying to divide by zero.");
    }
 
    return $this -> num1 / $this -> num2;
  }
 }
 
$targilim = array(
    array(8,1),
    array(9,0),
    array(4,2),
    array(6,1)
 );
 
foreach($targilim as $targil => $value){
  try{
    $calculate = new Calculate($value[0],$value[1]);
    echo $calculate -> divide();
    echo "<hr />";
  } catch (Exception $e){
    echo "Message: " . $e -> getMessage() . "<br />";
    echo "File: " . $e -> getFile() . "<br />";
    echo "Line: " . $e -> getLine() . "<br />";
    echo "<hr />";
    error_log($e->getMessage()." File:".$e->getFile()." Line:".$e->getLine());
  }
}

 

סדר ההוצאה לפועל של exception

כש-PHP מוציא לפועל קוד שכולל exception, במידה שמתרחש ה- exception, קוד ה-exception יקדים תמיד את האירוע החריג שהוא אמור למנוע כך שהאירוע החריג לא יצא לפועל, ובמקומו יתבצע חלק הקוד שתופס את ה-exception. בדוגמת הקוד הבאה, אנחנו אומנם קוראים קודם למתודה divide מתוך המחלקה Calculate, שקוראת בתורה למתודה is_zero מתוך המחלקה Validate, שזורקת exception במקרה של חלוקה באפס, אבל במקרה שננסה לחלק באפס, הקוד יזרוק את ה-exception, במקום לבצע את המתודה divide.

השרטוט הבא יכול לסייע להבין את בקרת הזרימה בקוד:

סדר הביצוע exception של PHP

וזה הקוד:

class Validate
{
  public function is_zero($num){
    if($num === 0){
      throw new Exception("Error! trying to divide by zero.");
    }
    return false;
  }
}
 
class Calculate
{
  private $num1;
  private $num2;
 
  public function __construct($num1,$num2){
    $this -> num1 = (int)$num1;
    $this -> num2 = (int)$num2;
  }
 
  public function divide(){
      $validate = new Validate();
    $validate -> is_zero($this -> num2);
 
    return $this -> num1 / $this -> num2;
  }
}
 
$targilim = array(
    array(8,1),
    array(9,0),
    array(4,2),
    array(6,1)
   );  
foreach($targilim as $targil => $value){
  try{
    $calculate = new Calculate($value[0],$value[1]);
    echo $calculate -> divide();
    echo "<hr />";
 
  } catch (Exception $e){
    echo "Message: " . $e -> getMessage() . "<br />";
    echo "<hr />";
  }
}

התוצאה היא שה-exception מהמחלקה Validate נזרק ויוצא לפועל במקום השגיאה שאנו מנסים למנוע במחלקה Calculate.

סדר הביצוע exception של PHP

 

לסיכום

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

 

המדריך מבוסס על "The essentials of Object Oriented PHP" שמלמד PHP מונחה עצמים באמצעות דוגמאות ותרגילים הקליקו על התמונה כדי לרכוש את ה-eBook:

eBook cover The essentials of Object Oriented PHP

 

לכל מדריכי ה-PHP מונחה עצמים

 

הוסף תגובה חדשה

 

= 8 + 4