Анонімні функції у PHP. PHP: Анонімні функції Як на практиці використовуються замикання

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

У 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.