PHP 5.3 – Closures & Lambda/Anonymous Functions

אחד מהאפשרויות החדשות שהוצגו ב PHP 5.3 הן האפשרות ליצור פונקציות בזמן הרצת הסקריפט, ללא צורך בהגדרת פונקציה עבור פעולה שמתבצעת ספציפית באותו המקום. Closures היא מילה נרדפת ל Lambda Function ו Anonymous Function, בדומה ל JS אפשרות זו יוצרת פונקציה וניתן להציב אותו למשתנה כלשהו. בתור התחלה זה יכול להראות כמשהו שהוא לא כל כך שימושי ופרקטי אבל עם הזמן אני מניח שיעשה יותר שימוש באפשרות זו.

דוגמא ל Closure

<?php
$closure = function($argument) { echo $argument; };
$closure = function($argument) use ($someVar) { // implement the 'use' keyword to store $someVar into the closure scope
echo $argument . ' ' . $someVar;
};
?>

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

דוגמאות לשימוש

<?php
$square = function($x)
{
    return $x*$x;
};
print $square(2);
?>

הקוד למעלה יחזיר את התוצאה 4.

אפשר כמובן להשתמש בזה בתוך פונקציה לדוגמא

<?php
function testFunction($number) {
    $sub = function($number) {
        return $number - 10;
    }
    return $sub;
}
echo testFunction(20);
?>

הקוד למעלה תחזיר את הערך 10.

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

<?php
print_r(
    array_map(
        function ($n) { return $n*$n; },
        array(1,2,3,4,5)
    )
);
?>

הקוד למעלה ידפיס את הנתון הבא:

Array
(
    [0] => 1
    [1] => 4
    [2] => 9
    [3] => 16
    [4] => 25
)

בנוסף לכך, PHP 5.3 ישנה אפשרות בשם ()invoke__ אשר בעצם מאפשר קריאה למחלקה כפונקציה אנונימית, קצת קשה יהיה להסביר את זה אני מקווה שדוגמא תעזור יותר:

<?php
class MyCustomClosure {
    function __invoke() {
        echo "I'm not really a closure, but you can treat me as one\n";
    }
}
$closure = new MyCustomClosure();
$closure();
?>

שוב זה אומנם נראה כמו משהו שהוא לא כל כך שמיש, אבל עם הזמן זה יתפתח למשהו שכן יעשה בו שימוש רב.