Php замыкания. В чем преимущество использования try {} catch {} по сравнению с if {} else {}. Пример обычной функции

Привет всем и сегодня мы поговорим о том, что такое анонимные функции в 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 и как их использовать . Удачи!

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

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

В этом примере мы присвоили переменной анонимную функцию, потом запустили выполнение этой функции синтаксисом $closure(); , то есть мы к имени переменной добавили круглые скобки, как при вызове функции. Обратите внимание, при этом знак $ в имени переменной мы не удаляли.

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

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

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

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

Тут мы создали обычную функцию doStuff() и передали ей как параметр нашу анонимную функцию из переменной $closure , а потом запустили её в теле функции doStuff() .

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

Функция is_callable()

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

Объекты класса Closure также называют псевдотипом Callbacks / Callables . Принадлежность переменной к этому типу данных можно проверить при помощи функции is_callable() .

"; print_r($closure); } } $closure = function(){ echo "Hello, World!"; }; doStuff($closure); ?>

Обратите внимание, функция gettype определяет тип переменной $closure как объект. Поэтому функция is_object также вернёт значение true , но это не адекватная проверка в нашем случае. Замыкание нужно проверять именно функцией is_callable .

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

В анонимной функции можно сделать видимой переменную из родительской области видимости используя конструкцию use . Вот пример:

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

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

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

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

" . $argument; }; doStuff($closure); ?>

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

Функция preg_replace_callback

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

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

Preg_replace_callback ($pattern , $callback, $subject)

  • $pattern - искомый шаблон, может быть как строкой, так и массивом строк.
  • $callback - вызываемая callback-функция, которой будет передан массив совпавших элементов из строки subject. Callback-функция должна вернуть строку с заменой.
  • $subject - строка или массив строк для поиска и замены.

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

Ещё функции принимающие аргументом замыкание: array_filter , array_map , array_reduce , usort .

Функция call_user_func

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

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

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

Класс Closure

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

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

Sum: " . ($variable + $variable_out); }; } $r = doStuff(); $r(35); doStuff()->__invoke(5);

я переключаюсь с простого 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) для того, чтобы встроенные языковые конструкции могли работать подобно пользовательским функциям.

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

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

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

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