В этом модуле вы изучите замыкания (closures) в PHP — мощный инструмент функционального программирования. Замыкания позволяют функциям захватывать переменные из внешней области видимости через ключевое слово use. Вы научитесь создавать анонимные функции с доступом к внешним переменным, понимать разницу между передачей по значению и по ссылке в замыканиях, использовать замыкания в callback-функциях и работать с ними в современных паттернах PHP. Замыкания особенно полезны при работе с массивами, создании фабрик функций и реализации паттерна "стратегия". Освоив этот материал, вы сможете писать более гибкий и выразительный код, используя функциональные возможности PHP.
- Модуль 1: Основы синтаксиса PHP
- Модуль 2: Переменные и типы данных
- Модуль 3: Операторы
- Модуль 4: Условные конструкции
- Модуль 5: Циклы
- Модуль 6: Массивы
- Индексированные массивы.
- Ассоциативные массивы.
- Многомерные массивы.
- Добавление элементов в массив.
- Удаление элементов из массива.
- Функция count().
- Функция array_push() и array_pop().
- Функция array_shift() и array_unshift().
- Функция array_merge().
- Функция array_slice().
- Функция array_splice().
- Функция in_array().
- Функция array_search().
- Функция array_keys() и array_values().
- Функция array_unique().
- Функция array_reverse().
- Сортировка: sort(), rsort().
- Сортировка: asort(), arsort().
- Сортировка: ksort(), krsort().
- Функция array_map().
- Функция array_filter().
- Функция array_reduce().
- Функция array_walk().
- Функция array_column().
- Деструктуризация массивов.
- Модуль 7: Функции
- Объявление функций.
- Вызов функций.
- Параметры функций.
- Возврат значений return.
- Значения параметров по умолчанию.
- Передача по значению.
- Передача по ссылке.
- Переменное количество аргументов.
- Оператор распаковки ....
- Типизация параметров.
- Типизация возвращаемых значений.
- Nullable типы.
- Union типы (PHP 8).
- Именованные аргументы (PHP 8).
- Анонимные функции.
- Стрелочные функции.
- Замыкания и use.
- Рекурсивные функции.
- Глобальные переменные в функциях.
- Статические переменные в функциях.
- Модуль 8: Работа со строками
- Одинарные и двойные кавычки.
- Экранирование символов.
- Heredoc и Nowdoc синтаксис.
- Функция strlen().
- Функция substr().
- Функция str_replace().
- Функция strpos() и strrpos().
- Функция explode() и implode().
- Функция trim(), ltrim(), rtrim().
- Функция strtolower() и strtoupper().
- Функция ucfirst() и ucwords().
- Функция str_repeat().
- Модуль 9: Суперглобальные переменные
- Модуль 10: Работа с формами
- Модуль 11: Работа с файлами
- Модуль 12: Дата и время
- Модуль 13: Регулярные выражения
- Модуль 14: Сессии и Cookie
- Модуль 15: Include и Require
- Модуль 16: Объектно-ориентированное программирование
- Модуль 17: Пространства имен
- Модуль 18: Обработка ошибок и исключений
- Модуль 19: Работа с JSON и XML
- Модуль 20: Работа с базами данных MySQLi
- Модуль 21: PDO - PHP Data Objects
- Модуль 22: Composer и зависимости
- Модуль 23: cURL и HTTP запросы
- Модуль 24: REST API
- Модуль 25: Безопасность
- Модуль 26: Генераторы и итераторы
- Модуль 27: Reflection API
- Модуль 28: Работа с изображениями
- Модуль 29: Отправка email
- Модуль 30: Паттерны проектирования
- Модуль 31: Тестирование
- Модуль 32: Продвинутые возможности PHP 8+
Базовое замыкание с use
Создайте замыкание, которое использует внешнюю переменную через use для формирования приветствия. Замыкание должно обращаться к переменной из внешней области видимости.
<?php
$greeting = "Добро пожаловать";
$welcomer = input1S($name) input2S (input3S) {
return input4S . ", " . $name . "!";
};
echo $welcomer("Анна");
?>Исправьте синтаксис замыкания с use
В коде есть синтаксические ошибки при объявлении замыкания с использованием внешних переменных. Найдите и исправьте ошибки в строках с замыканием.
<?php$counter = 0;$increment = function use (&$counter) () { return ++$counter;};echo $increment(); // 1echo $increment(); // 2?>Соберите фабрику функций с замыканием
Соберите код фабрики множителей - функции, которая создает другие функции с замыканием. Каждая созданная функция должна умножать входное число на заданный множитель.
echo $double(5); // 10<?php};function createMultiplier($factor) {$triple = createMultiplier(3);return function($number) use ($factor) {$double = createMultiplier(2);return $number * $factor;echo $triple(5); // 15?>echo $factor; // Ошибкаglobal $factor;Область видимости в замыкании
Определите, что выведет код с замыканием, которое захватывает переменную по значению.
<?php
$value = 10;
$closure = function() use ($value) {
return $value;
};
$value = 20;
echo $closure();
?>Передача по ссылке в замыкании
Создайте замыкание, которое изменяет внешнюю переменную, используя передачу по ссылке через use.
<?php
$total = 0;
$items = [10, 20, 30, 40];
$addToTotal = function($amount) use (input1S$total) {
input2S += $amount;
};
array_walk($items, input3S);
echo "Сумма: " . input4S;
?>Порядок выполнения с несколькими замыканиями
Расставьте строки кода в правильном порядке для создания системы логирования с использованием замыканий. Должен получиться код, который создает логгер с префиксом и использует его.
};$errorLog = createLogger("[ERROR]");<?phpreturn function($message) use ($prefix) {$infoLog("[INFO] Application started");function createLogger($prefix) {echo $prefix . " " . $message . PHP_EOL;$infoLog = createLogger("[INFO]");$errorLog("[ERROR] Connection failed");?>Замыкание с множественными переменными
Заполните пропуски, чтобы создать замыкание, использующее несколько внешних переменных для вычисления стоимости с учетом скидки и налога.
<?php
$discount = 0.1; // 10% скидка
$tax = 0.2; // 20% налог
$calculatePrice = function($price) input1S (input2S, input3S) {
$discounted = $price * (1 - input4S);
return $discounted * (1 + input5S);
};
echo $calculatePrice(100); // 108
?>Замыкание с изменением по ссылке
Определите, что выведет код с замыканием, которое модифицирует внешнюю переменную по ссылке.
<?php
$count = 5;
$modifier = function() use (&$count) {
$count *= 2;
return $count;
};
echo $modifier() . ",";
echo $count;
?>Исправьте замыкание с static переменной
В коде есть ошибка при использовании static переменной внутри замыкания для создания счетчика. Исправьте код так, чтобы счетчик работал правильно.
<?php$counter = function() { $static count = 0; return ++$count;}; echo $counter() . PHP_EOL; // 1echo $counter() . PHP_EOL; // 2echo $counter() . PHP_EOL; // 3?>Сопоставьте концепции замыканий с их описанием
Соотнесите термины и концепции замыканий в PHP с их правильным описанием.
function() { }use ($var)use (&$var)static $counter$closure->bindTo($object)Создайте каррированную функцию
Соберите код каррированной функции - функции, которая возвращает другую функцию, последовательно принимая аргументы. Функция должна складывать три числа.
<?phpfunction curry($a) { return function($b) use ($a) { return function($c) use ($a, $b) { return $a + $b + $c; }; };} $add5 = curry(5);$add5and3 = $add5(3);echo $add5and3(2); // 10?>echo curry(1)(2)(3); // 6return $a + $b; // неполная суммаuse ($c) // неверная переменнаяЗамыкание в цикле
Определите, что выведет код с замыканиями, созданными в цикле. Обратите внимание на момент захвата переменной.
<?php
$functions = [];
for ($i = 0; $i < 3; $i++) {
$functions[] = function() use ($i) {
return $i;
};
}
foreach ($functions as $func) {
echo $func();
}
?>Замыкание как метод обработки массива
Используйте замыкание с array_map для преобразования массива цен с учетом внешней переменной курса валюты.
<?php
$exchangeRate = 75.5; // курс доллара к рублю
$pricesUSD = [10, 25, 50, 100];
$pricesRUB = array_map(input1S($price) input2S (input3S) {
return round($price * input4S, 2);
}, input5S);
print_r($pricesRUB);
?>Вложенные замыкания с use
Определите результат выполнения кода с вложенными замыканиями, где внутреннее замыкание использует переменные из разных областей видимости.
<?php
$global = 10;
$outer = function($x) use ($global) {
return function($y) use ($x, $global) {
return $x + $y + $global;
};
};
$inner = $outer(5);
echo $inner(3);
?>Исправьте bindTo для замыкания
В коде есть ошибка при попытке привязать замыкание к объекту для доступа к его свойствам. Исправьте синтаксис привязки.
<?phpclass Calculator { private $tax = 0.15; public function getTaxCalculator() { return function($amount) { return $amount * $this->tax; }; }} $calc = new Calculator();$taxFunc = $calc->getTaxCalculator();$taxFunc->bindTo($calc);echo $taxFunc(100); // 15?>