Замыкания и use

Тренажер по PHP для пользователей с начальным уровнем подготовки.

Тренажер PHP

В этом модуле вы изучите замыкания (closures) в PHP — мощный инструмент функционального программирования. Замыкания позволяют функциям захватывать переменные из внешней области видимости через ключевое слово use. Вы научитесь создавать анонимные функции с доступом к внешним переменным, понимать разницу между передачей по значению и по ссылке в замыканиях, использовать замыкания в callback-функциях и работать с ними в современных паттернах PHP. Замыкания особенно полезны при работе с массивами, создании фабрик функций и реализации паттерна "стратегия". Освоив этот материал, вы сможете писать более гибкий и выразительный код, используя функциональные возможности PHP.

Список тем

Базовое замыкание с use

id: 38999_task1

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

Заполните пропуски
<?php
$greeting = "Добро пожаловать";

$welcomer = input1S($name) input2S (input3S) {
    return input4S . ", " . $name . "!";
};

echo $welcomer("Анна");
?>
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Исправьте синтаксис замыкания с use

id: 38999_task2

В коде есть синтаксические ошибки при объявлении замыкания с использованием внешних переменных. Найдите и исправьте ошибки в строках с замыканием.

Найдите ошибку и исправьте
<?php
$counter = 0;
$increment = function use (&$counter) () {
    return ++$counter;
};
echo $increment(); // 1
echo $increment(); // 2
?>
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Соберите фабрику функций с замыканием

id: 38999_task3

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

Перетяните в правильном порядке строки из одного блока в другой
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;
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Область видимости в замыкании

id: 38999_task4

Определите, что выведет код с замыканием, которое захватывает переменную по значению.

Выберите правильный вариант ответа
<?php
$value = 10;
$closure = function() use ($value) {
    return $value;
};
$value = 20;
echo $closure();
?>
Сообщения
Проверить
Показать подсказку

Передача по ссылке в замыкании

id: 38999_task5

Создайте замыкание, которое изменяет внешнюю переменную, используя передачу по ссылке через use.

Заполните пропуски
<?php
$total = 0;
$items = [10, 20, 30, 40];

$addToTotal = function($amount) use (input1S$total) {
    input2S += $amount;
};

array_walk($items, input3S);
echo "Сумма: " . input4S;
?>
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

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

id: 38999_task6

Расставьте строки кода в правильном порядке для создания системы логирования с использованием замыканий. Должен получиться код, который создает логгер с префиксом и использует его.

Расставьте строки в правильном порядке
};
$errorLog = createLogger("[ERROR]");
<?php
return function($message) use ($prefix) {
$infoLog("[INFO] Application started");
function createLogger($prefix) {
echo $prefix . " " . $message . PHP_EOL;
$infoLog = createLogger("[INFO]");
$errorLog("[ERROR] Connection failed");
?>
Сообщения
Проверить
Показать подсказку

Замыкание с множественными переменными

id: 38999_task7

Заполните пропуски, чтобы создать замыкание, использующее несколько внешних переменных для вычисления стоимости с учетом скидки и налога.

Нужно правильно расставить в пропуски предложенные варианты
<?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
?>
use
$discount
$tax
$discount
$tax
&$discount
&$tax
,
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Замыкание с изменением по ссылке

id: 38999_task8

Определите, что выведет код с замыканием, которое модифицирует внешнюю переменную по ссылке.

Что должно получиться?
<?php
$count = 5;
$modifier = function() use (&$count) {
    $count *= 2;
    return $count;
};

echo $modifier() . ",";
echo $count;
?>
Сообщения
Проверить
Показать подсказку

Исправьте замыкание с static переменной

id: 38999_task9

В коде есть ошибка при использовании static переменной внутри замыкания для создания счетчика. Исправьте код так, чтобы счетчик работал правильно.

Найдите ошибку и исправьте
<?php
$counter = function() {
    $static count = 0;
    return ++$count;
};
 
echo $counter() . PHP_EOL; // 1
echo $counter() . PHP_EOL; // 2
echo $counter() . PHP_EOL; // 3
?>
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Сопоставьте концепции замыканий с их описанием

id: 38999_task10

Соотнесите термины и концепции замыканий в PHP с их правильным описанием.

Сопоставьте строки в правой части с соответствующими строками в левой по порядковому номеру
Захват переменной по значению
Захват переменной по ссылке
Сохранение состояния между вызовами
Анонимная функция без захвата
Привязка замыкания к объекту
function() { }
use ($var)
use (&$var)
static $counter
$closure->bindTo($object)
Сообщения
Проверить
Показать подсказку

Создайте каррированную функцию

id: 38999_task11

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

Перетяните в правильном порядке строки из одного блока в другой
<?php
function 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); // 6
return $a + $b; // неполная сумма
use ($c) // неверная переменная
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Замыкание в цикле

id: 38999_task12

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

Выберите правильный вариант ответа
<?php
$functions = [];
for ($i = 0; $i < 3; $i++) {
    $functions[] = function() use ($i) {
        return $i;
    };
}

foreach ($functions as $func) {
    echo $func();
}
?>
Сообщения
Проверить
Показать подсказку

Замыкание как метод обработки массива

id: 38999_task13

Используйте замыкание с 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);
?>
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Вложенные замыкания с use

id: 38999_task14

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

Что должно получиться?
<?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 для замыкания

id: 38999_task15

В коде есть ошибка при попытке привязать замыкание к объекту для доступа к его свойствам. Исправьте синтаксис привязки.

Найдите ошибку и исправьте
<?php
class 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
?>
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку
🚀 Визуализатор кода
0 / 0
Скорость:
Режим:
💡 Что происходит?
Загрузите пример для начала...
🤔
Проверка знаний
История шагов
Готов
НайтиКурс.Ру