An answer that is very similar to the others, but with one - in my opinion, key - difference: rather than instantiating the dependency/dependencies in the constructor, pass them to the constructor:
class User { protected $db; public function __construct(Db $db) { $this->db = $db; } public function login($username, $password) { $this->db->query("SELECT * FROM users..."); } }
The benefits to this type of dependency injection include:
- It clearly demonstrates that the client/consumer class (
User) has a dependency (Db). - Reduces coupling between the
User class and the Db class. This helps significantly when unit-testing the User class. You can create a mock Db that performs as expected. Any test failures are then clearly attributable to the User class.
Of course, in order to instantiate a User object, you need to instantiate a Db object first. With a lot of dependencies for a single object or for a long chain of dependencies, this can be kind of a pain. In that case, it is helpful - but not required - to employ a Factory or a Dependency Injection Container to assist with this object creation.