אימגו מגזין מאמרים

כתב עת בנושאי תרבות ותוכן

רקורסיות ב PHP


תאריך פרסום קודם: 
30/06/2007
מחבר: 
ניסים עינת

רקורסיות ב שפת PHP

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

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

הסבר נוסף - כאן

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

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

שדה האב (parent) בטבלה יכיל את מספר שורת (id) האב.

דוגמה לפונקציה לתפריט ניווט היררכי אין סופי :

function menu_regular($p=0){ static $menu_output; static $i=0; $result = mysql_query("SELECT * FROM menu WHERE parent=$p AND approved='Y' ORDER BY ord DESC"); if($i==0){$ul_id=' id="navmenu"';} $menu_output.=""; $i++; while($row = mysql_fetch_array($result)){ $menu_output.="$row[name]"; menu_regular($row['id']); $menu_output.="\n"; } $menu_output.=""; $i=$i-1; return preg_replace("/]*>/si","",$menu_output); }

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

שימו לב כי תצטרכו לדאוג לקביעת כתובת הקישור (url) בעצמכם.

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

function check_parents_by_levels($id,$level,$table) { static $parent; static $j; if($level>$j) { $res=mysql_query("SELECT parent FROM $table WHERE id=$id"); if($row_parent=mysql_fetch_array($res)) { $j++; $parent=$row_parent['parent']; check_parents_by_levels($row_parent['parent'],$level,$table); }else { $j=10000000000; check_parents_by_levels(false,$level,$table); } } $j=null; return $parent; }

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

וישנם מקרים בהם אני רוצה לדעת אם שורה מסויימת נימצאת תחת ענף מסויים, כלומר אם אי שם ב "אילן היוחסין שלה" אחד האבות היא שורה עם id מסויים, עבור כך כתבתי את הפונקציה הבאה:

function check_parent($p,$id,$table){ static $parent; $res=mysql_query("SELECT parent FROM $table WHERE id='$id'"); $row=mysql_fetch_array($res); if($row[parent]==$p){$parent=$id;return $parent;} elseif($row[parent]==0){$parent=false;return false;} else{check_parent($p,$row[parent],$table);} return $parent; }

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

הסבר קצר על הרקורסיה הזו:

הפוקציה מקבלת שלושה ארגומנטים:

שם הטבלה - $table מספר ה id של שורת האב הנבדק $p השורה הנבדקת $id

הפונקציה תענה על השאלה: האם שורה ש ה id שלה שווה ל $p נמצא היכן שהוא במעלה אילן היוחסין של שורת $id . במקרה שכן, הפונקציה תחזיר את ערך האב $p ובמידה ולא הערך היוחזר יהיה false

Add new comment

CAPTCHA

This question is for testing whether you are a human visitor and to prevent automated spam submissions.

Fill in the blank.

הנצפים ביותר

מאמרים נוספים מאת ניסים עינת

.