PHP: Анонимные функции. Замыкания в PHP Знаешь что то о замыканиях в php

01.07.2023

В 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 . "
"; $closure(); echo $x . "
"; $closure(); echo $x . "
";

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

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

я переключаюсь с простого mysql в php на PDO, и я заметил, что общий способ проверки ошибок использует комбинацию try / catch вместо комбинаций if / else.

в чем преимущество этого метода, могу ли я использовать один блок try / catch вместо нескольких вложенных блоков if / else для обработки всех ошибок для разных шагов (connect, prepare, execute и т. д.)?

11 51

Jeroen

11 ответов:

выбрасывание и перехват исключения является дорогостоящей операцией по сравнению с большинством других примитивных операций. Если это фрагмент кода, который должен хорошо работать (например, в узком цикле), вы захотите посмотреть на свой вариант использования - если вы ожидаете, что исключения будут появляться относительно часто, вам будет лучше с помощью if/else perforance (если только базовый код не просто обертывает исключение для вас, и в этом случае нет никакого выигрыша). Если исключения только выбрасываются редкие обстоятельства, тогда вам лучше попробовать / поймать, чтобы избежать накладных расходов на ветвление в плотной петле.

поскольку PDO использует объекты, они вызывают исключения, если возникает ошибка. Старые mysql / mysqli были простыми функциями и не бросали исключений, они просто возвращали коды ошибок. Try / catch используется, когда исключение может быть вызвано из кода, и вы ловите его в предложении catch, которое является объектно-ориентированным способом обработки ошибок. Вы не можете поймать исключения с блоками if/else - они ничего не разделяют с try/catch.

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

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

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

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

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

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

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

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

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

Анонимные функции , или по-другому лямбда-функции - это функции, у которых нет имени.

Пример обычной функции

function FuName($txt) {
echo "My text: ".$txt;
}

$func = "FuName";
$func("My text");
?>

У нас есть функция, которая принимает один параметр. Дальше мы записываем имя функции в переменную и вызываем её. Ничего необычного. В ООП стиле это будет более оправдано.

class MyClass {
function bar() {
// код
}
}

$class = new MyClass();
$func = "bar";
$class->$func();
?>

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

Если вы знакомы с анонимными функциями из языка JavaScript , то вам понятно, зачем они нужны, а если нет, то читайте дальше.

Чтобы вызвать нашу анонимную функцию где-то дальше в коде программы, мы можем присвоить её переменной

$func = function() {
// код
};

$func();
?>

Заметьте, что в конце стоит ; , т.к. мы присваиваем переменной значение, равное функции. Но вся соль не в этом, а в том, что мы можем использовать эти функции в качестве callback-функций . Например:

$val = array_filter($input, function ($v) { return $v > 2; });
?>

Ключевое слово USE

Опять же, если вы знаете JavaScript , то это не будет для вас проблемой. Ключевое слово USE позволяет использовать приём замыкания , т.е. с его помощью мы можем достучаться до внешних переменных.

$mx = function ($high_val) {
return function ($val) use ($high_val) {
return $val > $high_val;
};
};

$i = array(1, 2, 3, 4, 5, 6, 7);
$o = array_filter($input, $max_comp(2));
?>

Здесь мы внутри нашей лямбда-функции используем глобальную переменную high_val . Чтобы это было возможным, мы должны после слова function и параметров в круглых скобках написать use и передать туда название внешней переменной, которую мы хотим использовать внутри кода функции.

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

$name = "Brian";
$setName = function($n) use(&$name) {
$name = $n;
};

$setName("David");
echo $name;
?>

Заключение

Итак, сегодня вы узнали, что такое анонимные функции в php и как их использовать . Удачи!

Похожие статьи