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

Замыкания в PHP

или в PHP — это обычные функции, но без имени. Давайте рассмотрим пример такой функции:

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

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

Как на практике используются замыкания

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

Давайте ещё усложним наш пример.

Функция is_callable()

Анонимные функции в PHP реализованы с помощью встроенного класса Closure (PHP 5 >= 5.3.0, PHP 7). То есть каждая анонимная функция является объектом этого класса.

Конструкция use

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

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

Аргументы в анонимных функциях

В анонимную функцию можно передать аргументы. Давайте для примера передадим один аргумент в нашу функцию.

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

Функция preg_replace_callback

Я обещал несколько встроенных в PHP функций, которые принимают в качестве аргумента замыкание, вот одна из них: preg_replace_callback

preg_replace_callback — выполняет поиск по регулярному выражению и замену с использованием callback-функции (замыкания).

Это краткий синтаксис, подробнее про возможности этой функции можно почитать на сайте мануала по PHP.

Функция call_user_func

Функция call_user_func — вызывает пользовательскую функцию, указанную в первом параметре. Возвращает результат функции, или FALSE в случае ошибки.

Примеры использования call_user_func :

Пример использования call_user_func в ООП.

Класс Closure

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

Источник

PHP: анонимные функции. Где и как использовать?

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

Обычная функция vs. анонимная функция

Обычная функция выглядит примерно так:

Вызывается следующим образом:

Анонимная функция (Closure), в PHP дает возможность создавать функцию без имени (например, без printName() как в примере выше). Они части используются в роли callback.

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

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

В самом конце вызываем анонимную функцию добавляя к переменной «()», тем самым делая из нее функцию:

Анонимная функция в переменной

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

Чтобы не мешать все в кучу, давайте создадим новый пример:

Анонимная функция как callback

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

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

array_map() проходится по массиву с вашим обозначенной callback функцией.

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

Смотрите новый вариант, который состоит всего из 5 строк:

Результат точно такой же как и в примере выше.

Создание Closure с анонимной функцией

Давайте рассмотрим такой приме:

Объяснение

php callback example

Логика doSomething() следующая:

Источник

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

So you will need to explicitly pass them in by reference if your closure cares about their contents over time:

//set up variable in advance
$myInstance = null ;

//$myInstance might be instantiated, might not be
if( SomeBusinessLogic :: worked () == true )
<
$myInstance = new myClass ();
>

Every instance of a lambda has own instance of static variables. This provides for great event handlers, accumulators, etc., etc.

In case you were wondering (cause i was), anonymous functions can return references just like named functions can. Simply use the & the same way you would for a named function. right after the `function` keyword (and right before the nonexistent name).

PERFORMANCE BENCHMARK 2017!

I decided to compare a single, saved closure against constantly creating the same anonymous closure on every loop iteration. And I tried 10 million loop iterations, in PHP 7.0.14 from Dec 2016. Result:

a single saved closure kept in a variable and re-used (10000000 iterations): 1.3874590396881 seconds

new anonymous closure created each time (10000000 iterations): 2.8460240364075 seconds

In other words, over the course of 10 million iterations, creating the closure again during every iteration only added a total of «1.459 seconds» to the runtime. So that means that every creation of a new anonymous closure takes about 146 nanoseconds on my 7 years old dual-core laptop. I guess PHP keeps a cached «template» for the anonymous function and therefore doesn’t need much time to create a new instance of the closure!

So you do NOT have to worry about constantly re-creating your anonymous closures over and over again in tight loops! At least not as of PHP 7! There is absolutely NO need to save an instance in a variable and re-use it. And not being restricted by that is a great thing, because it means you can feel free to use anonymous functions exactly where they matter, as opposed to defining them somewhere else in the code. 🙂

As of PHP 7.0, you can use IIFE(Immediately-invoked function expression) by wrapping your anonymous function with ().

public function __destruct ()
<
echo «destructed\n» ;
>
>

new Test ;
echo «finished\n» ;

public static function createClosure ()
<
return function () <
>;
>

When using anonymous functions as properties in Classes, note that there are three name scopes: one for constants, one for properties and one for methods. That means, you can use the same name for a constant, for a property and for a method at a time.

Since a property can be also an anonymous function as of PHP 5.3.0, an oddity arises when they share the same name, not meaning that there would be any conflict.

Consider the following example:

class MyClass <
const member = 1 ;

public function member () <
return «method ‘member'» ;
>

header ( «Content-Type: text/plain» );

$myObj = new MyClass ();

/*
* Establish mock authorisation, call the service; should get
* ‘Service returns: test 1’.
*/
$_SESSION [ ‘is_authorised’ ] = true ;
$service ( ‘test 1’ );

/*
* Remove mock authorisation, call the service; should get ‘Access Denied’.
*/
$_SESSION [ ‘is_authorised’ ] = false ;
$service ( ‘test 2’ );

Источник

Зачем нужен static при объявлении анонимных функций?

Буквально на днях пришел вопрос от одного из подписчиков касательно одного из постов моего telegram канала. Его смутил вот такой кусок кода

Зачем делать callback’и в функции сортировки (usort), статическими?

И я подумал, что это действительно хороший вопрос, на который стоит обратить внимание.

В чем проблема?

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

Анонимные функции, также известные как замыкания (closures), позволяют создавать функции, не имеющие определённых имён. Они наиболее полезны в качестве значений callable-параметров, но также могут иметь и множество других применений.

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

Там-же, но это почти никто не читает :

image loaderКод, чтобы протестить самостоятельно

На первый взгляд «да и чёрт с ним», но стоит копнуть чуть глубже.

Замыкание, содержащее ссылку на $this, может быть не обработано сборщиком мусора, что, в свою очередь, может существенно повлиять на производительность.

Вот пример без использования static:

Как результат, мы получим string(10) «134.10 MiB»

Но в случае, если мы добавим static в 11 строке, то потребление памяти составит string(8) «1.19 MiB»

Всё потому, что в processors[] мы продолжаем накапливать массив, внутри которого находятся Сlosures которые связаны с классом, а значит, содержат все те данные, которые в нём хранятся.

Выводы

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

Источник

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

Анонимные функции, также известные как замыкания (closures), позволяют создавать функции, не имеющие определенных имен. Они наиболее полезны в качестве значений callback-параметров, но также могут иметь и множество других применений.

Пример #1 Пример анонимной функции

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

Пример #2 Пример присвоения анонимной функции переменной

Замыкания могут также наследовать переменные из родительской области видимости. Любая подобная переменная должна быть объявлена в конструкции use.

Пример #3 Наследование переменных из родительской области видимости

// Сбросим message
$message = ‘hello’ ;

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

Пример #4 Замыкания и область видимости

// Базовая корзина покупок, содержащая список добавленных
// продуктов и количество каждого продукта. Включает метод,
// вычисляющий общую цену элементов корзины с помощью
// callback-замыкания.
class Cart
<
const PRICE_BUTTER = 1.00 ;
const PRICE_MILK = 3.00 ;
const PRICE_EGGS = 6.95 ;

Источник

Справочник по обустройству дома и дачи
Adblock
detector