Ответ
Магический метод __invoke() позволяет экземпляру объекта быть вызванным как функцию. Когда объект используется с синтаксисом вызова функции $object(), PHP автоматически вызывает его метод __invoke().
Основные сценарии использования:
- Объекты-функции (функторы): Создание объектов, которые хранят состояние между вызовами, в отличие от обычных функций.
- Callback-и с состоянием: Удобная передача в функции вроде
array_map,usort, где нужна не просто статическая логика, а конфигурируемое поведение. - Альтернатива замыканиям (closures) для сложной логики, которую удобно инкапсулировать в класс.
Практический пример — стратегия с состоянием:
class DiscountCalculator {
private $discountRate;
public function __construct(float $discountRate) {
$this->discountRate = $discountRate;
}
public function __invoke(float $price): float {
return $price * (1 - $this->discountRate);
}
}
// Создаем стратегии с разным состоянием (процентом скидки)
$regularDiscount = new DiscountCalculator(0.1); // 10%
$vipDiscount = new DiscountCalculator(0.25); // 25%
$prices = [100.0, 200.0, 300.0];
// Применяем разные стратегии как функции
$regularPrices = array_map($regularDiscount, $prices);
$vipPrices = array_map($vipDiscount, $prices);
print_r($regularPrices); // [90, 180, 270]
print_r($vipPrices); // [75, 150, 225]
Метод __invoke() стирает грань между объектами и функциями, позволяя использовать преимущества ООП (инкапсуляция, состояние) в контекстах, рассчитанных на функции.