В Wikipedia сказано, что анонимная функция это функция, которая может существовать без идентификатора. Звучит довольно-таки интересно! В этом уроке я покажу вам несколько примеров того, как можно создать и вызвать функцию нестандартными методами.
Начнём сразу с примеров:
function Test($var) {
echo "This is $var";
}
Это очень простая функция. Теперь помимо обычного вызова, мы можем запустить эту функцию при помощи переменной, которая хранит имя данной функции. Примерно вот так:
$f = "Test";
$f("variable function");
Если вы запустите код, то увидите сообщение This is variable function. К сведению сказать, обработка одинарных кавычек срабатывает быстрее, чем двойных.
Такую технику мы можем применять и в ООП. Пример с php.net:
class Foo
{
function Variable()
{
$name = 'Bar';
$this->$name(); // This calls the Bar() method
}
function Bar()
{
echo "This is Bar";
}
}
$foo = new Foo();
$funcname = "Variable";
$foo->$funcname(); // This calls $foo->Variable()
Это концепция довольно интересна. Она может быть использована для реализации обратных вызовов, таблиц функций и так далее.
Теперь я попробую объяснить вам, что такое анонимные функции:
$input = array(1, 2, 3, 4, 5);
$output = array_filter($input, function ($v) { return $v > 2; });
function ($v) { return $v > 2; } это анонимная функция. Так же мы можем присвоить её переменной, чтобы использовать в дальнейшем.
$max = function ($v) { return $v > 2; };
$input = array(1, 2, 3, 4, 5);
$output = array_filter($input, $max);
Теперь познакомимся с новым ключевым словом use. Напишем для этого другую анонимную функцию (работает с PHP 5.3):
$max_comp = function ($max) {
return function ($v) use ($max) { return $v > $max; };
};
$input = array(1, 2, 3, 4, 5);
$output = array_filter($input, $max_comp(2));
В этом примере мы используем эффект замыкания при помощи ключевого слова use. Эта техника позволяет анонимной функции получать доступ к внешним переменным. Повеяло ветерком процедурного программирования?
Вот ещё один пример попроще:
$string = "Hello World!";
$closure = function() use ($string) { echo $string; };
$closure();
Как я уже сказал, переменные, которые мы хотим использовать (из глобальной области видимости) в таких функциях необходимо передавать через use. Важно отметить, что по умолчание передаётся только значение, так что если вы хотите менять содержание передаваемой переменной и хотите, чтобы оно менялось за пределами анонимной функции, передавайте значение по адресу:
$x = 1;
$closure = function() use (&$x) { ++$x; };
echo $x . "<br />";
$closure();
echo $x . "<br />";
$closure();
echo $x . "<br />";
В этом примере, наш метод изменяет содержание переменной $x при каждом вызове анонимной функции. Если бы мы не передавали адрес переменной, а саму переменную у нас бы вывелось три 1.
Истинная красота «замыкания» в том, что оно не загромождает глобальное пространство имён. Как только анонимная функция выполнила действие, все переменные использующиеся в ней уничтожаются автоматически.