Роут: PHP: return function (App $app) { $app->get('/{id:\d+}', ExampleAction::class); }; Обработчик: PHP: readonly class Handler implements HandlerInterface { public function __construct( private ContainerInterface $container, private RouteResult $routeResult ) { } public function handle(Request $request): Response { return call_user_func( $this->container->get($this->routeResult->getAction()), $request, new Response(), ...$this->routeResult->getParameters() ); } } Теперь я хочу, чтобы везде в экшенах каждый раз не писать вручную внедрение Request и Response, написать интерфейс: PHP: interface ActionInterface { public function __invoke(Request $request, Response $response): Response; } В итоге имеем такой вот экшен: PHP: class ExampleAction implements ActionInterface { public function __invoke(Request $request, Response $response, int $id): Response { var_dump($id); return $response; } } Ошибка: должно соответствовать интерфейсу Как помирить экшен с интерфейсом, учитывая splat? p.s. я могу не сплатом передать массив в интерфейс, который тупо совпадёт с массивом экшена, но есть желание именно сплатом доставать переменные, без обработки массива в экшене, ну и чтобы его не прописывать, если работы с ним не будет - пустой
@Вероломство ну я чего ты хотел, сигнатура метода другая, чем в ActionInterface! Сделай тогда splat (spread) в самом интерфейсе и его имплементирующих классах. Чтобы было одинаково. Вообще это выглядит как грязный хак, ИМХО. Строгость в типах и сигнатурах помогает писать надёжный код, а такие хаки пробивают дыру в строгости. --- Добавлено --- Еще ты можешь сделать интерфейс вообще без методов, просто имя задать и где-то его вставлять в implements. Зависит от твоих целей.
@artoodetoo вообще-то да, хак, облегчающий, вылазит вилами, ведь может быть и не __invoke кстати если сплатовому параметру задать дефолт, то работает, но мне не нравится дефолт, потому что тогда паттерн решает наличие роута, а он же может быть необязательным отказался от интерфейса экшену, повёлся на автокомплит IDE при имплементации, если не будет шторма, то всё одно руками писать затупил лан порешали, в топку интерфейс запроса и ответа
@artoodetoo вопрос небольшой по дефолту: а это вообще нормально если так делать, работать работает, но интуитивно посещают сомнения в правильности такого подхода: PHP: interface ActionInterface { public function __invoke(Request $request, Response $response): Response; } class ExampleAction implements ActionInterface { public function __invoke(Request $request, Response $response, int $id = 0): Response { var_dump($id); return $response; } } Имеет такое право на жизнь?
По моему нескромному мнению, так делать нельзя даже если PHP такое пропустит. Я в последнее время топлю за типизацию, соответствие нормам, против костылей. Пользуюсь статическим анализом кода phpstan. Послабления выходят боком. Какие-нибудь газенбаги всплывают или после обновления система раком встает. Нормально делай, нормально будет )))