I’m moving from Globals and Singletons (=bad?) to Dependency Injections (=good?) in PHP and I’m very new to it.
I have read many related topics on Stack Overflow already but I still can’t understand the main principles of DI.
Please tell me if I’m doing it right (it’s just shortened pseudo-code):
// first connect to DB
$sql = new Sql();
// create logger (I'm writing logs to Database so I need to pass $sql to it)
$log = new Log($sql);
// restore logged in user, get info about user, unread messages...
// class "User" needs access to Database and Logs:
$user = new User($sql, $log);
// now we need to collect all the data of current section of my Website
// I'm using Model and Controller:
$model = new FrontPageModel($sql, $user, $log);
$pageController = new FrontPageController($model);
Though it may look OK at this step but what if I need to get access to more classes like Config, Session, etc.?
Should my code transform to this?
$model = new FrontPageModel($sql, $user, $log, $config, $session);
Isn’t it too much already?
I know someone could advice to use a kind of big “Application” class and put Config, Session, Log, Db objects inside of this class but I feel that it isn’t very good idea.
Next question – what if I need to get logged User’s ID inside of my FrontPageController? I did not pass an instance of “User” to FrontPageController, but it was passed before (in chain) to FronPageModel.
class FrontPageController{
private $model;
function __construct($model){
$this->model = $model;
}
function getData(){
echo $this->model->user->id; // is it right way?
}
}
That “$this->model->user->id” seems like overkill to me.
It might not be the prettiest, but you’re certainly not doing it “wrong”. You’re demonstrating classing constructor injection, but you could perhaps refactor to keep some of the disparate objects separated a bit more.
My suggestion would be to look at established PHP DI containers. See how they work, use them in a few apps, and (1) you’ll have much more testable apps and (2) you’ll be much more comfortable with DI in general.
Take a look at one or more of the following: