Что такое анонимная функция php
Перейти к содержимому

Что такое анонимная функция php

  • автор:

Что такое анонимная функция php

Анонимные функции позволяют передавать в качестве параметров функции другие функции или присваивать их переменным.

Анонимная функция определяется как обычная функция за тем исключением, что она не имеет имени. Например:

$hello = function($name) < echo "

Hello $name

"; >;

Здесь переменной $hello присваивается анонимная функция. Эта функция также определяется с помощью ключевого слова function . Она также принимает параметры — в данном случае параметр $name . И также она имеет некоторый блок операторов.

Для вызова подобной функции применяется имя представляющей ее переменной:

$hello("Tom");

Фактически подобная переменная применяется как стандартная функция.

Hello $name"; >; $hello("Tom"); $hello("Bob"); ?>

Анонимные функции в PHP

Также анонимные функции могут возвращать некоторое значение:

; $number = $sum(5, 11); //16 echo $number; ?>

Распространенным случаем применения анонимных функций является передача их параметрам других функции. Таким анонимные функции еще называют функциями обратного вызова или коллбеками (callback function). Рассмотрим простейший пример:

 welcome(function() < echo "Hello!"; >); ?>

В данном случае функция welcome() имеет параметр $message , который внутри функции вызывается подобно функции $message() .

При вызове функции welcome() параметру $message передается анонимная функция, которая выводит строку «Hello!». В этоге при вызове

$message();

Фактически будет выполняться функция

function()

Подобным образом мы можем передавать одну функцию различные анонимные функции:

 $goodMorning = function() < echo "

Доброе утро

"; >; $goodEvening = function() < echo "

Добрый вечер

"; >; welcome($goodMorning); // Доброе утро welcome($goodEvening); // Добрый вечер welcome(function()< echo "

Привет

"; >); // Привет ?>

Анонимные функции callback в PHP

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

function sum($numbers) < $result = 0; foreach($numbers as $number)< $result += $number; >return $result; > $myNumbers = [-2, -1, 0, 1, 2, 3, 4, 5]; $numbersSum = sum($myNumbers); echo $numbersSum; // 12

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

 > return $result; > // для четных чисел $isEvenNumber = function($n)< return $n % 2 === 0;>; // для положительных чисел $isPositiveNumber = function($n) < return $n >0;>; $myNumbers = [-2, -1, 0, 1, 2, 3, 4, 5]; $positiveSum = sum($myNumbers, $isPositiveNumber); $evenSum = sum($myNumbers, $isEvenNumber); echo "Сумма положительных чисел: $positiveSum 
Сумма четных чисел: $evenSum"; ?>
Сумма положительных чисел: 15 Сумма четных чисел: 4

Здесь функция sum() в качестве второго параметра — $condition принимает другую функцию. В цикле при переборе массива с помощью этой функции мы проверяем, удовлетворяет ли элемент массива условию:

if($condition($number))

Причем сейчас мы не значем, что это будет за условие, как именно функция $condition будет работать. Мы только знаем, что она получает число и возвращает true , если число удовлетворяет условию, либо false — если не удовлетворяет.

И если только число соответствует условию, тогда прибавляем число к общему результату:

$result += $number;

При вызове функции sum() в качестве параметра $condition передаются конкретные анонимные функции. Например, функиция, которая определяет, является ли число четным:

$isEvenNumber = function($n)< return $n % 2 === 0;>;

Логика функции проста: если остаток от деления числа на 2 равен 0, то число четное. и функция возвращает true .

Далее мы передаем эту функицию:

$evenSum = sum($myNumbers, $isEvenNumber);

В итоге при вызове if($condition($number)) фактически будет выполняться функция $isEvenNumber() .

Что такое анонимная функция php

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

Вначале рассмотрим анонимную функцию, которая пытается использовать некоторую внешнюю переменную:

; $showNumber(); ?>

Анонимная функиция, которая представлена переменной $showNumber , пытается обратиться к внешней переменной $number. Однако при выполнении скрипта мы увидим в браузере сообщение об ошибке:

Warning: Undefined variable $number in C:\localhost\hello.php on line 13

То есть по умолчанию переменной $number для анонимной функции не существует. Из данной сиутации мы можем выйти, использовав оператор global или массив $GLOBALS , которые рассматриваются в одной из последующих тем. Тем не менее замыкания также позволяют решить эту проблему. Так, трансформируем функцию в замыкание:

; $showNumber(); ?>

Выражение use() получает внешние переменные, которые анонимная функция собирается использовать. И теперь при ее выполении браузер выведет значение переменной $number .

Подобным образом функция-замыкание может захватывать и большее количество внешних переменных, а также как и другие функции применять параметры:

$a = 8; $b = 10; $closure = function($c) use($a, $b) < return $a + $b + $c; >; $result = $closure(22); // 40 echo $result;

PHP: Анонимные функции

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

\n"; > $my_func = 'foo'; // Теперь мы можем запустить функцию foo() при помощи переменной $my_func, // которая хранит имя указанной функции в виде строки $my_func(); // Вызываем функцию foo() ?>

Такая концепция PHP имеет название «переменные-функции». Она заключается в том, что если добавить к переменной в конце круглые скобки, то интерпретатор PHP проверит сначала, не существует ли функции с именем равным значению переменной и если такая функция есть — выполнит ее.

Так, как показано в примере выше, можно делать только с функциями определенными пользователями. Встроенные языковые конструкции и функции, такие как echo, unset(), isset() и другие подобные им нельзя таким же образом напрямую присвоить переменным. Но можно сделать свою функцию-обертку (wrapper) для того, чтобы встроенные языковые конструкции могли работать подобно пользовательским функциям.

 $my_func = 'foo'; $my_func('test'); // Вызывает функцию foo() ?>

Анонимные функции

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

; // точка с запятой обязательна $my_func('World!'); ?>

Обратите внимание на пример, в конце определения функции есть точка с запятой, так как анонимная функция является по своей сути значением, и мы присваиваем значение переменной, то в конце как и для обычных инструкций ставится точка с запятой.

Анонимные функции отличаются от именованных тем, что создаются только в тот момент, когда до них доходит выполнение, поэтому воспользоваться ими можно только после их определения:

С этой темой смотрят:

  • Определение и вызов функции
  • Параметры и аргументы функции
  • Литералы, идентификаторы и инструкции
  • Переменные
  • Область видимости

Копирование материалов с данного сайта возможно только с разрешения администрации сайта
и при указании прямой активной ссылки на источник.
2011 – 2024 © puzzleweb.ru | razumnikum.ru

Что такое анонимная функция php

Стрелочные функции появились в PHP 7.4 как лаконичный синтаксис для анонимных функций.

Основной вид записи стрелочных функций: fn (argument_list) => expr .

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

Когда стрелочная функция использует переменную, которую определили в родительской области, переменная неявно захватывается по значению. В следующем примере функции $fn1 и $fn2 ведут себя одинаково.

Пример #1 Стрелочные функции захватывают переменные по значению автоматически

$fn1 = fn( $x ) => $x + $y ;
// эквивалентно использованию $y по значению:
$fn2 = function ( $x ) use ( $y ) return $x + $y ;
>;

var_export ( $fn1 ( 3 ));

Результат выполнения приведённого примера:

Это также работает во вложенных стрелочных функциях:

Пример #2 Стрелочные функции захватывают переменные по значению автоматически, даже когда они вложены

$z = 1 ;
$fn = fn( $x ) => fn( $y ) => $x * $y + $z ;
// Выведет 51
var_export ( $fn ( 5 )( 10 ));

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

Пример #3 Примеры использования стрелочных функций

fn(array $x ) => $x ;
static fn(): int => $x ;
fn( $x = 42 ) => $x ;
fn(& $x ) => $x ;
fn&( $x ) => $x ;
fn( $x , . $rest ) => $rest ;

Стрелочные функции используют привязку переменных по значению. Это примерно эквивалентно выполнению use($x) для каждой переменной $x , используемой внутри стрелочной функции. Привязка по значению означает, что невозможно изменить какие-либо значения из внешней области. Вместо этого можно использовать анонимные функции для привязок по ссылкам.

Пример #4 Стрелочные функции не умеют изменять значения из внешней области видимости

$x = 1 ;
$fn = fn() => $x ++; // Ничего не изменит
$fn ();
var_export ( $x ); // Выведет 1

Список изменений

Версия Описание
7.4.0 Стали доступны стрелочные функции.

Примечания

Замечание: Можно вызывать функции func_num_args() , func_get_arg() и func_get_args() в стрелочной функции.

User Contributed Notes 5 notes

3 years ago

Unlike anonymous functions, arrow functions cannot have a void return type declaration.

May seem obvious, but if you thought you could make use of the benefits of arrow functions (using variables from the parent scope) to simplify a function or method call, keep in mind that this is only possible if you do NOT tell PHP that the arrow function does indeed return void.

3 years ago

In example 4 (Values from the outer scope cannot be modified by arrow functions)

$x = 1 ;
$fn = fn() => $x ++; // Has no effect
$fn ();
var_export ( $x ); // Outputs 1

?>

Here we can use reference variable in fn(&$x) and pass the value from function call $fn($x) so that we will get the output as expected with out using Anonymous functions.

?>

Output : 2 (as expected)

But here it will not take values from parent scope automatically but we have to pass them explicitly.

2 years ago

As you already know, variable bindings occur in arrow functions by «by-value». That means, an arrow function returns a copy of the value of the variable used in it from the outer scope.

Now let us see an example of how a arrow function returns a reference instead of a copy of a value.

$fn = fn &(& $x ) => $x ; // Returns a reference

$y = & $fn ( $x ); // Now $y represents the reference

var_dump ( $y ); // Outputs: 0

$y = 3 ; // Changing value of $y affects $x

var_dump ( $x ); // Ouputs: 3

3 years ago

Beware compact() not being able to access (import) variables from external scope (known in versions: 7.4.0, 7.4.8) (bug: https://bugs.php.net/bug.php?id=78970).

A workaround is available — use the variable directly; this will cause it to be imported into the arrow function’s namespace and make it available to the compact() too.

$aa = 111 ;
$accessing_variable_works = fn( $bb ) => [ $aa , $bb ];
$compact_is_broken = fn( $bb ) => compact ( ‘aa’ , ‘bb’ );
$compact_can_work_with_workaround = fn( $bb ) => compact ( ‘aa’ , ‘bb’ ) + [ ‘workaround’ => $aa ];
var_dump ( $accessing_variable_works ( 333 ));
var_dump ( $compact_is_broken ( 555 ));
var_dump ( $compact_can_work_with_workaround ( 777 ));
?>

result:
array(2) [0]=>
int(111)
[1]=>
int(333)
>
PHP Notice: compact(): Undefined variable: aa in /home/m/vlt/guitar/tlb/s/public_html/index.php on line 9
array(1) [«bb»]=>
int(555)
>
array(3) [«aa»]=>
int(111)
[«bb»]=>
int(777)
[«workaround»]=>
int(111)
>

3 years ago

(fn() => print( $x ))(); // Outputs 1

(fn( $x ) => print( $x ))( 2 ); // Outputs 2

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *