
הגדרת פונקציות ב-PHP
פונקציות הן בלוקי קוד הניתנים לשימוש חוזר. לאחר הגדרת הפונקציה, ניתן לקרוא לה ממקומות שונים בקוד כמה פעמים שרוצים. פונקציות יכולות לקבל ערכים, לבצע פעולות ולהחזיר תוצאות.
קיימות מספר סיבות לשימוש בפונקציות:
- שימוש חוזר - כתיבת קטע קוד פעם אחת ושימוש שלו פעמים רבות.
- מודולריות - חלוקה של התוכנית ליחידות פונקציונליות נפרדות.
- תחזוקה - קל יותר לנפות באגים ולבצע שינויים ושיפורים עתידיים.
- קריאות - לוגיקה עצמאית משפרת את ההבנה של הקוד.
תחביר:
function functionName($param1, $param2) {
// Code to execute
return $result; // Optional
}
דוגמה:
<?php
function sayHello($name) {
return "Hello, $name";
}
echo sayHello("David"); // Output: Hello, David
?>
בדוגמה זו, הגדרנו פונקציה בשם sayHello. הפונקציה מקבלת פרמטר יחיד בשם name. באמצעות הפקודה return, מחזירה הפונקציה את המחרוזת Hello, name בהתאם לערך של המשתנה name. ניתן לראות שביצענו קריאה לפונקציה עם הערך David והדפסנו את ערך החזרה עם הפונקציה echo. על המסך יכתב Hello, David.
פרמטרים, ארגומנטים וערכי חזרה של פונקציות ב-PHP
פונקציה יכולה לקבל ערכים שונים ולהשתמש בהם. המשתנים המתקבלים בפונקציה ומשמשים בתוכה נקראים פרמטרים. הערכים המועברים לפונקציה מבחוץ נקראים ארגומנטים.
דוגמה:
<?php
function mult($a, $b) {
return $a * $b;
}
echo mult(3, 5); // Output: 15
?>
בדוגמה זו, הגדרנו את הפונקציה mult המקבלת 2 פרמטרים (a ו-b) ומחזירה את ערך ההכפלה שלהם. אנו מבצעים קריאה לפונקציה עם הארגומנטים 3 ו-5. בעת ריצת הפונקציה, הפרמטר a מחזיק את הערך 3 והפרמטר b מחזיק את הערך 5.
פונקציה יכולה גם לא לקבל ערכים כלל.
דוגמה:
<?php
function printWelcomeMessage() {
echo 'Welcome home!';
}
printWelcomeMessage();
?>
בדוגמה זו, הפונקציה printWelcomeMessage אינה מקבלת כלל פרמטרים. היא מדפיסה על המסך הודעה ומסיימת. ניתן לראות שהפונקציה כלל אינה מבצעת return, כיוון שאין חובה לכך. חשוב לזכור שבקריאה לפונקציה תמיד יש לציין סוגריים לצד שם הפונקציה, גם אם לא מועברים אליה ארגומנטים (במקרה כזה הסוגריים יהיו ריקים).
פונקציה יכולה להחזיר ערכים שונים במצבים שונים.
דוגמה:
<?php
function evaluateNumber($number) {
if ($number > 0) {
return "Positive number";
} elseif ($number < 0) {
return "Negative number";
} else {
return "Zero";
}
}
// Test the function
echo evaluateNumber(10); // Output: Positive number
echo evaluateNumber(-5); // Output: Negative number
echo evaluateNumber(0); // Output: Zero
?>
בדוגמה זו, ערך החזרה של הפונקציה evaluateNumber יהיה בהתאם למספר המועבר כארגומנט לפונקציה: גדול, קטן או שווה לאפס.
ניתן להגדיר פונקציה שחלק מהפרמטרים שלה אינם חובה. במקרה כזה, נקבע לפרמטרים האלו ערך ברירת מחדל. כאשר הפונקציה מקבלת כמה פרמטרים שחלקם חובה וחלקם אינם חובה (וכוללים ערך ברירת מחדל), הפרמטרים שאינם חובה צריכים להיות האחרונים ברשימת הפרמטרים של הפונקציה.
דוגמה:
<?php
function calculateArea($shape, $length, $width = 0, $pi = 3.14) {
if ($shape === "circle") {
return $pi * $length * $length; // Area of a circle (length = radius)
} elseif ($shape === "rectangle") {
return $length * $width; // Area of a rectangle
} elseif ($shape === "square") {
return $length * $length; // Area of a square
} else {
return "Invalid shape.";
}
}
// Test the function
echo calculateArea("circle", 5); // Output: 78.5 (Area of a circle)
echo calculateArea("rectangle", 4, 6); // Output: 24 (Area of a rectangle)
echo calculateArea("square", 3); // Output: 9 (Area of a square)
echo calculateArea("circle", 5, 0, 3.14159); // Output: 78.53975 (Using more precise pi)
?>
בדוגמה זו, הגדרנו פונקציה בשם calculateArea לחישוב שטחים. הפונקציה מקבלת 4 פרמטרים, אשר 2 הפרמטרים האחרונים שלה אינם חובה ומקבלים ערך ברירת מחדל: הפרמטר width מקבל את ערך ברירת המחדל 0 והפרמטר pi מקבל את ערך ברירת המחדל 3.14. קראנו לפונקציה בפעם הראשונה עם 2 פרמטרים, בפעם השניה עם 3 פרמטרים, בפעם השלישית עם 2 פרמטרים ובפעם הרביעית עם 4 פרמטרים.
העברת פרמטרים כרפרנס
כברירת מחדל, העברת פרמטרים לפונקציות ב-PHP נעשית על בסיס ערך (by value). כלומר, הארגומנטים המועברים לפונקציה מועתקים לעותק נוסף המשתמש בפונקציה. שינוי הערך הפנימי בפונקציה אינו משנה את הערך המקורי שמחוץ לפונקציה.
דוגמה:
<?php
function inc($num) {
$num++;
}
$x = 5;
inc($x);
echo $x; // Output: 5
?>
בדוגמה זו, המשתנה x מאותחל לערך 5. בקריאה לפונקציה inc מעבירים את x כארגומנט והפרמטר num מקבל את הערך 5. בתוך הפונקציה inc, מגדילים את הערך של num ב-1 וערכו הופך להיות 6. עם זאת, הערך של x לא משתנה ונותר 5.
בהצהרת הפונקציה, ניתן לקבוע כי פרמטרים יועברו כרפרנס (by reference) ולא על בסיס ערך. לשם כך, נשתמש בסימן & לצד הפרמטר המועבר כרפרנס. המשמעות של העברת פרמטר כרפרנס היא ששינוי הפרמטר משנה ממש את הארגומנט שהועבר.
דוגמה:
<?php
function inc(&$num) {
$num++;
}
$x = 5;
inc($x);
echo $x; // Output: 6
?>
בדוגמה זו, תיקנו את הפונקציה inc מהדוגמה הקודמת והוספנו את הסימן & לצד הפרמטר num בהצהרה של הפונקציה. העברת הארגומנט x נעשית כרפרנס, וכל שינוי של הפרמטר num משנה ממש את x. קריאה לפונקציה inc מגדילה את num ב-1, ומכאן שגם x גדל ב-1. למעשה, הפרמטר num מייצג ממש את x עצמו (הוא רפרנס אליו), וכל שינוי ב-num הוא שינוי ב-x (ולא על עותק של x כמו בדוגמה המקורית).
האופרטור שלוש נקודות (...)
ניתן להגדיר פונקציות שמקבלות מספר לא מוגדר של פרמטרים. הדבר נעשה באמצעות האופרטור 3 נקודות (...) בשורת ההגדרה של הפונקציה. כל הערכים שמועברים לפונקציה יאספו למערך אחד כולל.
דוגמה:
<?php
function sum(...$numbers) {
return array_sum($numbers);
}
echo sum(1, 2, 3, 4); // Output: 10
?>
בדוגמה זו, הגדרנו את הפונקציה sum שמקבלת פרמטרים ללא הגבלה. הפרמטר numbers הוא למעשה מערך שמאגד בתוכו את כל הארגומנטים שמועברים לפונקציה. הפונקציה מחשבת את סכום הערכים באמצעות array_sum.
אם הפונקציה מקבלת מספר פרמטרים, הפרמטר האחרון הוא זה שיעשה שימוש באופרטור 3 נקודות.
דוגמה:
<?php
function calculateTotalPrice($basePrice, $taxRate, ...$discounts) {
// Start with the base price
$total = $basePrice;
// Apply discounts
foreach ($discounts as $discount) {
$total -= $discount;
}
// Add tax
$total += $total * ($taxRate / 100);
return $total;
}
// Test the function
echo calculateTotalPrice(100, 10); // Output: 110 (No discounts)
echo calculateTotalPrice(100, 10, 5); // Output: 105.5 (One discount of 5)
echo calculateTotalPrice(100, 10, 5, 10, 20); // Output: 75.9 (Discounts of 5, 10, 20)
?>
בדוגמה זו, הגדרנו את הפונקציה calculateTotalPrice שמקבלת את הפרמטר basePrice (מחיר בסיס), taxRate (שיעור המס) ופרמטרים נוספים שמהווים הנחות שמאוגדים תחת פרמטר המערך discounts. הפונקציה מחשבת את עלות המוצר הסופית שנקבעת לפי מחיר הבסיס בהפחתת כל ההנחות שהועברו לפונקציה, כפול שיעור המס.
פונקציה אנונימית והצהרת use
פונקציות אנונימיות, נקראות גם סגירות (closures), הן פונקציות שאין להן שם מוגדר. ב-PHP, פונקציות אנונימיות משמשות לעתים קרובות כארגומנטים המועברים לפונקציות אחרות או ליצירת פונקציות זמניות שמשתמשים בהם באופן חד פעמי.
כאשר עושים שימוש בפונקציה אנונימית, נחסכת התקורה (overhead) המיותרת של הגדרתה בנפרד.
ניתן לבצע השמה של פונקציה אנונימית למשתנה. במקרה כזה, הפעלת הפונקציה באמצעות המשתנה אפשרית על ידי הוספת סוגריים לצד המשתנה (עם או בלי פרמטרים המועברים לפונקציה).
דוגמה:
<?php
$sayHello = function($name) {
return "Hello, $name!";
};
echo $sayHello("John"); // Output: Hello, John!
?>
בדוגמה זו, הגדרנו פונקציה אנונימית שמקבלת פרמטר name ומדפיסה Hello, name. הפונקציה אנונימית מכיוון שאין לה שם. ביצענו השמה של הפונקציה למשתנה בשם sayHello, והפעלנו את הפונקציה באמצעות פניה למשתנה הזה עם הארגומנט John.
ניתן להעביר פונקציה אנונימית כפרמטר לפונקציות שונות.
דוגמה:
<?php
$numbers = [1, 2, 3, 4, 5];
$squared = array_map(function($n) {
return $n * $n;
}, $numbers);
print_r($squared); // Output: [1, 4, 9, 16, 25]
?>
בדוגמה זו, הפעלנו את הפונקציה array_map עם שני פרמטרים: הפרמטר הראשון הוא פונקציה אנונימית שמקבלת פרמטר n ומחזירה את הריבוע שלו, והפרמטר השני הוא מערך מספרים numbers. את תוצאת הפונקציה array_map הכנסנו למשתנה squared והדפסנו אותו.
בהצהרה של פונקציה אנונימית, נוכל להשתמש בפקודה use, כדי לעשות שימוש במשתנים שהוגדרו קודם לכן.
דוגמה:
<?php
$multiplier = 2;
$double = function($n) use ($multiplier) {
return $n * $multiplier;
};
echo $double(5); // Output: 10
?>
בדוגמה זו, המשתנה multiplier הוגדר בטרם הגדרת הפונקציה האנונימית. אנו נעזרים בפקודה use, כדי לאפשר לפונקציה האנונימית לעשות שימוש במשתנה הזה.
נשים לב ששימוש במשתנים באמצעות use אינו מאפשר שינוי של המשתנה (ערך המשתנה מועתק לפונקציה). כדי לאפשר שינוי של ערך המשתנה שהוגדר מחוץ לפונקציה, נעביר את המשתנה כרפרנס (באמצעות האופרטור &).
דוגמה:
<?php
$total = 0;
$add = function($n) use (&$total) {
$total += $n;
};
$add(5);
$add(10);
echo $total; // Output: 15
?>
בדוגמה זו, הגדרנו פונקציה אנונימית שעושה שימוש במשתנה total שהוגדר קודם לכן. המשתנה מועבר כרפרנס ולכן הפונקציה יכולה לשנות את ערכו. הפונקציה האנונימית משוייכת למשתנה add והקריאות לפונקציה נעשות באמצעות המשתנה add עם פרמטר.
פונקציית חץ
PHP מאפשרת להגדיר פונקציות פשוטות, כאלו הכוללות ביטוי מתמטי יחיד, בצורה קצרה יותר. צורה זו מכונה "פונקציית חץ" בשל ההגדרה שכוללת סימן דמוי חץ.
פונקציית חץ הינה סוג של פונקציה אנונימית, כלומר, זוהי פונקציה שאין לה שם מוגדר.
תחביר:
fn(parameter_list) => expression;
דוגמה:
<?php
// Traditional anonymous function
$square = function($x) {
return $x * $x;
};
// Equivalent arrow function
$square = fn($x) => $x * $x;
echo $square(5); // Output: 25
?>
בדוגמה זו, הגדרנו את הפונקציה square, המחשבת את הריבוע המתמטי של מספר (מכפלת המספר בעצמו). ניתן לראות שביצענו את הגדרת הפונקציה פעמיים: בפעם הראשונה כפונקציה אנונימית שאינה פונקציית חץ ובפעם השניה באמצעות פונקציית חץ.
פונקציית חץ יכולה לעשות שימוש במשתנים שהוגדרו באותו הסקופ (אותו בלוק קוד) שבה היא מוגדרת ולפני הגדרתה.
דוגמה:
<?php
$factor = 10;
// Define an arrow function that uses $factor
$multiply = fn($x) => $x * $factor;
// Call the arrow function before changing $factor
echo $multiply(2); // Output: 20
// Change the value of $factor
$factor = 5;
// Call the arrow function again
echo $multiply(2); // Output: 20 (Still uses the original value of $factor)
?>
בדוגמה זו, הגדרנו את פונקציית החץ multiply שמקבלת פרמטר x ומכפילה אותו בערך המשתנה factor שהוגדר בטרם הגדרת הפונקציה ואותחל עם הערך 10. נשים לב שמרגע שהוגדרה הפונקציה עם הערך של factor שהיה 10 בעת ההגדרה, שינוי המשתנה factor אינו משפיע על ביצוע הפונקציה והיא תמשיך להכפיל תמיד ב-10. במילים אחרות, אפשר לומר שהמשתנה factor מחושב by value ולא by reference, כי ערכו מועתק בעת הגדרת הפונקציה.
פונקציית חץ שימושית במיוחד כאשר עושים מניפולציות מתמטיות על מערכים, למשל באמצעות הפונקציות array_map או array_filter.
דוגמה:
<?php
$numbers = [1, 2, 3, 4, 5];
// Using arrow function to double each value
$doubled = array_map(fn($n) => $n * 2, $numbers);
print_r($doubled); // Output: [2, 4, 6, 8, 10]
?>
בדוגמה זו, הפונקציה array_map מקבלת את פונקציית החץ כפרמטר ראשון, ואת המערך numbers כפרמטר שני, והיא מפעילה את פונקציית החץ על כל אחד מאיברי המערך numbers.
השימוש בפונקציית חץ משמש בעיקר להגדרת פונקציות מתמטיות פשוטות. יתרונה של פונקציית החץ הוא בכך שהיא קצרה וקריאה יותר.
פונקציה רקורסיבית ב-PHP
פונקציה רקורסיבית היא פונקציה שקוראת לעצמה במהלך ביצועה. גישת הרקורסיה מאפשרת לפתור משימות על ידי חלוקתן למשימות דומות וקטנות יותר. הרקורסיה שימושית במיוחד עבור בעיות שניתן להגדירן במונחים של תת-בעיות קטנות יותר, כגון סריקה של עצי נתונים, גרפים או ספריות קבצים, פתרון בעיות מתמטיות שמבוססות סדרות (כגון פעולת עצרת) ועוד.
מרכיבי מפתח של פונקציות רקורסיביות:
- בסיס הרקורסיה - המצב שבו הרקורסיה נעצרת. ללא בסיס הרקורסיה, הפונקציה תקרא לעצמה ללא הגבלת זמן, דבר שיוביל להצפת מחסנית (Stack Overflow) שהיא הצפת הזכרון עם נתוני העומק של הרקורסיה.
- מקרה הרקורסיה - החלק של הפונקציה שבו היא קוראת לעצמה לטיפול בבעיית משנה קטנה יותר או פשוטה יותר.
תחביר סטנדרטי של פונקציה רקורסיבית:
function recursiveFunction($parameter) {
// Base case
if (condition) {
return result;
}
// Recursive case
return recursiveFunction(modifiedParameter);
}
דוגמה:
<?php
function factorial($n) {
if ($n === 0) { // Base case
return 1;
}
return $n * factorial($n - 1); // Recursive case
}
echo factorial(5); // Output: 120
?>
בדוגמה זו, הגדרנו פונקציה רקורסיבית בשם factorial שמחשבת את הפעולה המתמטית עצרת. בסיס הרקורסיה: אם הפונקציה מקבלת את הארגומנט 0 היא מחזירה 1 (כי עצרת של 0 זה 1). מקרה הרקורסיה: אם הפונקציה מקבלת מספר כלשהו אחר, היא תחזיר את המכפלה של אותו מספר בעצרת של המספר פחות 1. כלומר, חישוב של עצרת של 3 יחזיר 3 כפול עצרת של 2. חישוב עצרת של 2 יחזיר 2 כפול עצרת של 1. חישוב עצרת של 1 יחזיר 1 כפול עצרת של 0 (שהיא כאמור 1).
דוגמה נוספת:
<?php
function fibo($n) {
if ($n === 0) { // Base case
return 0;
}
if ($n === 1) { // Base case
return 1;
}
return fibonacci($n - 1) + fibonacci($n - 2); // Recursive case
}
echo fibo(6); // Output: 8
?>
בדוגמה זו, הגדרנו פונקציה רקורסיבית בשם fibo שמחשבת את הסדרה המתמטית פיבונאצ'י. סדרת פיבונאצ'י היא סדרה שבה כל איבר שווה לסכום שני האיברים שלפניו. זו הסדרה: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 וכן הלאה. הפונקציה כוללת 2 בסיסי רקורסיה: אם היא מקבלת את הארגומנט 0 היא מחזירה 0 ואם היא מקבלת את הארגומנט 1 היא מחזירה 1. מקרה הרקורסיה: אם הפונקציה מקבלת מספר כלשהו אחר, היא תחזיר את הסכום של הפיבונאצ'י של הערך פחות אחד, עם הפיבונאצ'י של הערך פחות 2.
היתרון של הפונקציה הרקורסיבית הוא קוד פשוט, אלגנטי וקריא יותר, במיוחד עבור בעיות ספציפיות שניתן לחלק לתתי בעיות דומות. החסרונות של הפונקציה הרקורסיבית הם איטיות ביצוע (כי בכל העמקה של הרקורסיה פנימה, המחסנית ששומרת את נתוני הפונקציה הופכת גדולה יותר), סכנה מפני לולאות אינסופיות במקרה של מקרי קצה שלא נלקחו בחשבון, וקשיים לאתר בעיות (debugging).
במקרים בהם ניתן לפתור בעיות בצורה פשוטה יחסית וללא רקורסיה, נמליץ להמנע משימוש בפונקציה רקורסיבית.
סקופינג של משתנים: משתנים לוקאליים, גלובליים, סופר גלובליים וסטטיים
סקופינג מתייחס להקשר שבתוכו משתנה נגיש. כלומר, החלקים בקוד בהם ניתן להשתמש במשתנה שהגדרנו.
ל-PHP יש ארבעה סוגים של משתנים: משתנים לוקאליים, משתנים גלובליים, משתנים סופר גלובליים ומשתנים סטטיים. נסקור סוגי משתנים אלו להלן.
משתנה לוקאלי (מקומי)
משתנים לוקאליים, המכונים גם משתנים מקומיים, הם משתנים המוגדרים בתוך פונקציה. ניתן לגשת למשתנה לוקאלי רק מתוך הפונקציה בה הוא מוגדר.
דוגמה:
<?php
function myFunc() {
$localVar = "I am local!";
echo $localVar; // Outputs: I am local!
}
myFunc();
// echo $localVar; // Error: Undefined variable
?>
משתנה גלובלי
משתנים גלובליים הם משתנים המוגדרים מחוץ לכל פונקציה. ניתן לגשת למשתנה גלובלי מכל מקום בסקריפט, למעט מתוך פונקציות או מחלקות.
כדי להנגיש משתנה גלובלי בתוך פונקציה (כלומר, לאפשר שימוש במשתנה גלובלי בתוך פונקציה), יש להשתמש במילה השמורה global.
דוגמה:
<?php
$globalVar = "I am global!";
function showVar() {
global $globalVar; // Import global variable into the local scope
echo $globalVar; // Outputs: I am global!
}
showVar();
?>
משתנה סופר גלובלי (Superglobal)
משתנים סופר גלובליים הם משתנים מיוחדים המוגדרים מראש ב-PHP. משתנים אלו נגישים בכל מקום בקוד: בתוך פונקציות ומחוץ לפונקציות. בתור מוסכמת שמות, משתנים אלו מתחילים בסימן קו תחתי (_) מיד לאחר סימן ה-$.
דוגמה:
<?php
$_SESSION['username'] = "JohnDoe";
echo $_SESSION['username']; // Outputs: JohnDoe
?>
משתנה סטטי
משתנים סטטיים הם משתנים המוגדרים בתוך פונקציה, עם המילה השמורה static. משתנה סטטי שומר על ערכו לאורך כל התוכנית, בניגוד למשתנים לוקאליים אשר מוגדרים מחדש בכל כניסה לפונקציה.
דוגמה:
<?php
function countCalls() {
static $count = 0; // Static variable
$count++;
echo $count;
}
countCalls(); // Outputs: 1
countCalls(); // Outputs: 2
countCalls(); // Outputs: 3
?>
נשים לב שמשתנה גלובלי מוגדר פעם אחת ושומר על ערכו לאורך כל התוכנית. באופן הזה, משתנים גלובליים הם כמו משתנים סטטיים, מלבד ההבדל שהם פועלים בסקופ הגלובלי במקום בסקופ של פונקציה ספציפית.
משתנים גלובליים ומערך GLOBALS
מערך GLOBALS הוא מערך סופר גלובלי המאפשר גישה למשתנים גלובליים מכל מקום בסקריפט, כולל פונקציות ומחלקות פנימיות. הדבר שימושי במיוחד כאשר רוצים לגשת למשתנה גלובלי מבלי להשתמש במפורש במילת המפתח global.
דוגמה:
<?php
$globalVar = "Hello, Global!";
function showGlobal() {
echo $GLOBALS['globalVar']; // Access the global variable via the GLOBALS array
}
showGlobal(); // Outputs: Hello, Global!
?>
משתני סביבה
משתני סביבה הם משתנים שמוגדרים חיצונית לסקריפט ה-PHP והם יכולים להשפיע על ההתנהגות של PHP. הם משמשים בדרך כלל למטרות תצורה (configuration), כגון אחסון הרשאות מסדי נתונים, מפתחות API או מידע רגיש אחר. ניתן לגשת למשתני סביבה באמצעות המערך הסופר גלובלי ENV.
דוגמה:
<?php
// Assuming an environment variable 'DB_HOST' is set
$dbHost = $_ENV['DB_HOST'];
echo "Database Host: $dbHost"; // Outputs the value of the 'DB_HOST' environment variable
?>