Интернет Windows Android

Замыкания в PHP. Анонимные, или лямбда-функции в php Как на практике используются замыкания

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

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

В этом примере мы присвоили переменной анонимную функцию, потом запустили выполнение этой функции синтаксисом $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);