Description
Symfony version(s) affected
5.4.x, 6.2.x
Description
If you want to use ServiceSubscriberTrait
in a class that happens to extend from AbstractController
, the following error will appear:
Symfony\Component\ErrorHandler\Error\FatalError:
Compile Error: Declaration of
Symfony\Contracts\Service\ServiceSubscriberTrait::setContainer(Psr\Container\ContainerInterface $container)
must be compatible with
Symfony\Bundle\FrameworkBundle\Controller\AbstractController::setContainer(Psr\Container\ContainerInterface $container): ?Psr\Container\ContainerInterface
at src/Controller/AppAbstractController.php
The point of ServiceSubscriberTrait::setContainer
is that it automatically looks for a setContainer
method in the parent class and uses it, if available. However, that's incompatible in this case, as the parent setContainer
method has a more specific return type.
How to reproduce
namespace App\Controller;
use Doctrine\DBAL\Connection;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Contracts\Service\ServiceSubscriberTrait;
class AppAbstractController extends AbstractController
{
use ServiceSubscriberTrait;
private function databaseConnection(): Connection
{
return $this->container->get(__METHOD__);
}
}
Possible Solution
I did not create a PR right away as I am not sure whether this can technically only be fixed in Symfony 7? But if it's not fixed the ServiceSubscriberTrait
is unusable for cases where a parent class actually implements setContainer
with a specific return type.
Though may be instead of changing the return type for ServiceSubscriberTrait::setContainer
the return type of AbstractController::setContainer
should be removed, which should be safe to do in a bugfix release. After all, the ContainerAwareInterface
and ContainerAwareTrait
also do not use a return type on setContainer
.
Additional Context
No response