К выходу PHP 8.3 я решил реализовать фичу, которая в новой версии не только не появилась, но и была окончательно выпилена (с чем я согласен).
Итак, вот мой вариант оверлоадинга/перегрузки/Ad-hoc-полиморфизма для PHP:
use Typhoon\Overloading\Overload;
final readonly class WhateverHandler
{
public function handle(mixed ...$args): string
{
return Overload::call();
}
#[Overload('handle')]
public function handleInt(int $int): string
{
return __METHOD__;
}
#[Overload('handle')]
public function handleIntAndFloat(int $int = 0, float $float = M_E): string
{
return __METHOD__;
}
}
$handler = new WhateverHandler();
// WhateverHandler::handleInt
var_dump($handler->handle(300));
// WhateverHandler::handleIntAndFloat
var_dump($handler->handle(float: 1.5));
В перегружаемый метод пишем один-единственный вызов
Overload::call(). Он, кстати, специально ничего не принимает, чтобы упростить использование и избежать ошибок. Затем добавляем перегружающие методы с такой же статичностью/видимостью и помечаем их атрибутом #[Overload('перегружаемый метод')]. Вуаля! Теперь можно вызывать перегружаемый метод с аргументами различных типов, а Overload будет передавать поток управления в методы с подходящей сигнатурой.Главный вопрос, конечно, скорость. Но несмотря на то, что это реализация в первом приближении и есть идеи по улучшению, уже работает достаточно шустро. Благодаря мемоизации в воркерах капитальной разницы с прямым вызовом не будет, особенно если перегруженных методов не очень много. Для PHP-FPM предусмотрен кэш с поддержкой OPcache (примерно как в докладе).
Короче, ставьте, экспериментируйте, закидывайте идеи в комментарии и в Issues в репозиторий.
https://github.com/typhoon-php/overloading
P.S. Всех с третьей восьмёркой! 🎉