As more and more service oriented PHP is being done these days, I find myself with a lot of PHP files that have this long chunk of code just for initialization. In other languages like C++ or typescript you can do the following without all the duplication. A PHP example:
namespace Test\Controllers;
use Test\Services\AppleService;
use Test\Services\BananaService;
use Test\Services\PearService;
use Test\Services\LemonService;
use Test\Services\PeachService;
class TestController{
protected $appleService;
protected $bananaService;
protected $lemonService;
protected $pearService;
protected $peachService;
public function __construct(
AppleService $appleService,
BananaService $bananaService,
LemonService $lemonService,
PearService $pearService,
PeachService $peachService
){
$this->appleService = $appleService;
$this->bananaService = $bananaService;
$this->lemonService = $lemonService;
$this->pearService = $pearService;
$this->peachService = $peachService;
}
}
A Typescript Example:
module namespace Test.Controllers {
export class TestController{
constructor(
private appleService:Test.Services.AppleService,
private bananaService:Test.Services.BananaService,
private lemonService:Test.Services.LemonService,
private pearService:Test.Services.PearService,
private peachService:Test.Services.PeachService
){}
}
}
Are there better/shorter ways to do the same thing, and/or is any support to make this easier planned for upcoming PHP releases?
There is an alternative, property injection:
use DI\Annotation\Inject;
class TestController
{
/**
* @Inject
* @var AppleService
*/
private $appleService;
/**
* @Inject
* @var BananaService
*/
private $bananaService;
/**
* @Inject
* @var LemonService
*/
private $lemonService;
/**
* @Inject
* @var PearService
*/
private $pearService;
/**
* @Inject
* @var PeachService
*/
private $peachService;
}
Is that shorter, or simpler to write? I'll let you judge. But I love it, I don't end up with a bloated constructor. This is inspired from Java/Spring FYI.
Now this example works with PHP-DI (disclaimer: I work on that), but there may be other DI containers that offer the same functionality.
WARNING: property injection doesn't fit everywhere.
I find it appropriate for controllers (since controllers are not supposed to be reused). Read more here.
I don't think it would be appropriate to use it in services. So that's not the ultimate solution.