Php анонимные функции синтаксис

Погружение в Closure и анонимные функции в PHP

Замыкания и анонимность — это то, что мне было трудно изучить во всей экосистеме PHP, не потому, что я, вероятно, сошел с ума, а потому, что нет хорошего и подробного объяснения того, что именно они собой представляют и как их можно использовать.

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

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

Безымянная функция . _ Анонимная функция выглядит так:

В отличие от обычных функций, анонимная функция не имеет имени.

Теперь представьте, если вы хотите использовать анонимную функцию, как вы это сделаете? в основном (можно использовать в функциях первого класса) это невозможно сделать. Итак, чтобы помочь в этом, реализована привязка имени, позволяющая хранить всю анонимную функцию в файле variable . Когда это сделано, это variable становится тем, что называется Closure

Что такое замыкание в PHP?

Класс , который ( тип ) используется для представления анонимной функции . Это может звучать очень странно, в PHP есть встроенный класс Closure . Когда создается анонимная функция, ее тип автоматически равен object(Closure) . Помните о динамической типизации PHP. Вот почему на практике Closure является анонимной функцией .

Чтобы доказать это, попробуйте следующее:

Переменная , содержащая анонимную функцию

Когда анонимная функция связана с переменной, эта переменная становится объектом класса Closure , следовательно, также является функцией Closure/anonymous .

На пути понимания этого

Во-первых, попробуйте создать объект/экземпляр класса Closure .

PHP Catchable fatal error: Instantiation of 'Closure' is not allowed 
  • Класс Closure не предназначен для создания экземпляров; его конструктор имеет значение private .
  • Класс ничего не возвращает и не имеет параметров.

Некоторые факты об этом классе

  • У него всего 5 методов: __construct() , __invoke() , bindTo() , call() , bind()
  • Метод __construct() существует только для того, чтобы запретить создание экземпляра класса
  • Это точно не интерфейс
  • Класс является окончательным
Читайте также:  Html forms codes example

Небольшое пояснение

Нам не нужно создавать экземпляр Closure , так как PHP делает это каждый раз, когда функция создается без имени, поэтому теперь я могу сделать:

Проблема как его так использовать??

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

$closureFunction = function() < return true; >; //never forget this semi-colon

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

echo $closureFunction; // PHP Catchable fatal error: Object of class Closure could not be converted to string; 

Как функция

echo test($closureFunction); //PHP Catchable fatal error: Object of class Closure could not be converted to string 

Независимо от того, где вы пытаетесь echo это сделать, вы всегда будете получать эту ошибку. Чтобы доказать это, давайте var_dump посмотрим, что мы пытаемся повторить:

var_dump($closureFunction); var_dump(test($closureFunction));
object(Closure)#1 (0) < >object(Closure)#1 (0)

Переменная, содержащая нашу nameless функцию, на самом деле содержит объект типа Closure .

Что произошло, как функция превратилась в объект?

Прежде чем я отвечу, давайте копнем дальше, установив параметр функции:

$closureFunction = function($var) < return $var; >; function test($var) < return $var; >var_dump($closureFunction); // object(Closure)#1 (1) < ["parameter"]=>array(1) < ["$var"]=>string(10) "" > > var_dump($closureFunction('ok')); // string(2) "ok" echo($closureFunction('ok')); // ok var_dump(test($closureFunction)); //object(Closure)#1 (1) < ["parameter"]=>array(1) < ["$var"]=>string(10) "" > > var_dump(test($closureFunction('ok'))); // string(2) "ok" var_dump(test($closureFunction($closureFunction))); // object(Closure)#1 (1) < ["parameter"]=>array(1) < ["$var"]=>string(10) "" > >

Отсюда пока:

  • функция nameless находится в переменной
  • мы можем использовать его где угодно, так как можно использовать переменную, кроме ее повторения
  • функция становится объектом класса Closure

Объяснение магии:

  • Тот факт, что класс Closure реализует __invoke , означает, что мы можем вызывать его экземпляры как вызов функции, например $var() . Если this: $var = function()<>; является объектом Closure , он позволяет нам использовать его $var с таким параметром, как $var($parameter) . В этом случае класс называется вызываемым .
  • Замыкания считаются первоклассными типами значений , как и string or integer . Это на самом деле секрет. Закрытие — это тип, определенный в движке PHP как тип, и вы не видите, когда именно они генерируются.

Какая польза?

Их использование зависит в основном от вашего варианта использования и потребностей. Тем не менее, вы можете использовать их как:

— Callables/Callback работают следующим образом:

$items = [1, 2]; $closure = function($x, $y)< echo __FUNCTION__, " got $x and $y"; >; call_user_func_array ($closure , $items );

— Наследование переменных , подобное этому:

 $msg = 'Hello'; $closure = function () use ($msg) < var_dump($msg); >; $closure();

— Присвоение переменной

$eat = function($food)< echo "I am eating some ", $food."
"; >; $eat('Bananas'); $eat('Apples');

— чтобы прикрепить состояние следующим образом:

function brand($name) < return function ($slogan) use ($name)< return sprintf('%s : %s', $name, $slogan); >; > $brand = brand('Dell'); print $brand('The power to do more.');
$recursive = function () use (&$recursive) < return $recursive; >; print_r($recursive());

Некоторые практические варианты использования

  • В большинстве современных фреймворков замыкания используются для маршрутизации.
  • Закрытие также используется при разработке корзин для покупок.
Читайте также:  How to check errors in php

Заключение

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

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

Я также признаю, что не могу сказать/объяснить все. Если у вас есть плюс, пожалуйста, добавьте его под этим уроком в качестве комментария. Спасибо за чтение.

Источник

Php анонимные функции синтаксис

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

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

$hello = function($name) < echo "

Hello $name

"; >;

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

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

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

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

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

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

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

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

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

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

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

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

 $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 принимает другую функцию. В цикле при переборе массива с помощью этой функции мы проверяем, удовлетворяет ли элемент массива условию:

Читайте также:  Enumeration and enum in java

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

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

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

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

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

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

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

Источник

Оцените статью