I have recently undertaken upgrading an old Symfony 4.4 app (to 5.4 and PHP 8.1) and have been following the brilliant tutorials over at symfonycasts.com. I have come up to a point where I don't understand how to move forward.
class One extends AbstractClassTwo {}
abstract class AbstractClassTwo extends AbstractClassThree {
public function __construct(array $arr = []){
parent::__construct();
$this->arr = $arr;
}
}
abstract class AbstractClassThree {
public function __construct(protected string $injectedVar) {}
public function doSomething() {
echo $this->injectedVar;
}
}
services.yaml:
_defaults: autowire: true autoconfigure: true bind: 'string $injectedVar': '%env(TO_INJECT)%'
.env.local:
TO_INJECT=astringgoeshere
When I try to execute the code I get: Uncaught Error: Too few arguments to function App\AbstractClassThree::__construct(), 0 passed in /src/AbstractClassTwo on line 35 and exactly 1expected.
I'm really unsure as to why this doesn't work. Any help much appreciated!
So the only way I seem to be able to solve this is to inject the parameters into the child class as well thus becomming:
abstract class AbstractClassTwo extends AbstractClassThree {
public function __construct(protected string $injectedVar, array $arr = []){
parent::__construct($injectedVar);
$this->arr = $arr;
}
}
The Symfony documentation itself does state:
These advantages do mean that constructor injection is not suitable for working with optional dependencies. It is also more difficult to use in combination with class hierarchies: if a class uses constructor injection then extending it and overriding the constructor becomes problematic.
Emphasis mine, this can be found just above the following link: https://symfony.com/doc/current/service_container/injection_types.html#immutable-setter-injection