Не сумасшедший, хотя я ожидал бы, что те же самые люди, которые сказали вам, как не делать вещи, также предложили бы некоторый совет о том, как сделать их.
Один из подходов состоит в том, чтобы разбить ControllerTrait (он же AbstractController) на более мелкие черты.
Например:
trait RouterTrait
{
/** @var RouterInterface */
protected $router;
/** @required NOTE THIS */
public function setRouter(RouterInterface $router)
{
$this->router = $router;
}
protected function generateUrl(
string $route,
array $parameters = array(),
int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): string
{
return $this->router->generate($route, $parameters, $referenceType);
}
protected function redirect($url, $status = 302) : RedirectResponse ...
protected function redirectToRoute($route, array $parameters = array(), $status = 302) : RedirectResponse ...
@required перед методом setRouter - это мало используемая аннотация, которая заставляет контейнер автоматически вводить службу маршрутизатора.
На этом этапе любой контроллер или любая другая служба, которая использует черту маршрутизатора, будет иметь доступ к вспомогательным функциям маршрутизатора.
Например:
class UserCreateAction implements ActionInterface
{
use GuidTrait;
use RouterTrait;
...
public function __invoke(Request $request)
{
...
return $this->redirectToRoute('reg_person_register');
Композиция над наследованием может быть хорошей вещью.
Один последний не по теме совет. Существует мало или нет причин использовать FOSRestBundle, если только он не предназначен для поддержки устаревших проектов. Платформа API на базе Symfony - действительно готовое решение для новых проектов.