Анонимные функции в PHP (замыкания, closures)

Анонимные функции (замыкания) в PHP

Начиная с версии 5.3 в PHP появились так называемые замыкания (closures), их еще называют анонимными функциями, они же известны как лямбда-функции. Замыкания так же могут быть использованы в качестве значений переменных (помещаться в переменные), при этом они автоматически преобразуются в экземпляр внутреннего класса Closure.

Анонимные функции нашли широкое применение в современных фреймворках, так же есть задачи, которые значительно облегчило применение анонимных функций, помните usort? Я приводил пример сортировки массива с использованием анонимной функции, это как раз один из таких случаев, когда лямбда-функция является наилучшим решением. Но не стоит их пихать по всюду, для каждого решения есть свой инструмент, масса Российских и не только программеров суют замыкания везде куда только могут, потом в итоге код становится абсолютно не читаемым.

Рассмотрим простой пример анонимной функции:

<?php

$func = function()
    {
        return "привет я анонимная функция";
    };

echo $func();
?>

Как и любая функция, лямбда-функция может что-то возвращать или выполнять какое-либо действие, в нашем случае функция возвращает строку и результатом выполнения скрипта будет вывод данной строки на экран: “привет я анонимная функция”.

Помимо всего, в PHP как и во многих языках программирования существуют области видимости, например внутри функции мы можем использовать только переданные в нее аргументы и созданные внутри ее переменные, но так же можно наследовать функции переменные из родительской области видимости. То есть функция сможет внутри себя использовать переменные и объекты, которые были определены за ее пределами. Рассмотрим пример ниже:

<?php

$string = "привет я анонимная функция";

$func = function() use($string)
    {
        return $string;
    };

echo $func();
?>

Результат будет тот же, что и в первом примере, но вот только строка содержится в переменной из родительской области видимости. Используемые переменные можно передавать в любом количестве, как и аргументы. Рассмотрим пример с использованием аргументов, при этом поместим функцию так же в переменную.

<?php

$calc = function($a, $b)
    {
        return ($a + $b);
    };

echo $calc(2, 3);

?>

Мы поместили функцию-калькулятор в переменную $calc, после того вывели на экран результат ее выполнения с двумя параметрами $a и $b, равными 2 и 3 соответственно, результат их суммирования будет выведен на экран оператором echo.

Функция не обязательно должна что-то возвращать (делать return), в нее можно передать не саму переменную, а лишь ссылку на нее, рассмотрим пример ниже:

<?php

$array = [1, 3, 4, 6, 2, 5, 7, 8, 9];

$sort = function(&$array)
    {
        usort($array, function($a, $b)
            {
                if ($a === $b)
                    {
                        return 0;
                    }
                else
                    {
                        return (($a > $b) ? 1 : -1);
                    }
            });
    };

$sort($array);

print_r($array);
?>

В результате выполнения данного скрипта будет выведен в консоль отсортированный массив, но при этом наша функция его не вернула после сортировки, но отсортировала реальный массив снаружи, так как получила на него ссылку.

Нет ничего сложного в использовании замыканий, они бывают очень удобны в нужных местах, главное не “перемудрить”, а то вы позже сами не сможете разобраться в своем коде. Есть такой принцип разработки, называется KISS – рекомендую его соблюдать.

KISS-принцип (от англ. keep it simple, stupid — «будь попроще, дурачок…») — принцип, запрещающий использование более сложных средств, чем необходимо. Изречение часто вызываемое при обсуждении вопросов проектирования с целью парирования нарастающей функциональности и управления сложностью разработки.

 

Подпишитесь на рассылку новых статей

Подпишитесь на рассылку свежих статей и присоединяйтесь к 7 остальным подписчикам.