Easy Dependency Injection

after reading this question, I wonder if anyone can help me figure out how to properly inject dependency injection with these PHP classes:

class DBClass { private $mMysqli; function __construct(mysqli $database) { $this->mMysqli=$database; } function __destruct() { $this->mMysqli->close(); } public function listUsers() { $query='SELECT * FROM Utente;'; $resultset=$this->mMysqli->query($query); while($row = $resultset->fetch_array(MYSQLI_ASSOC)) { echo $row['username']; echo $row['pwd']; echo "<br />\n"; } } public function runQuery($query) { return $resultset=$this->mMysqli->query($query); } public function getConnection() { return $this->mMysqli; } } 

Session Class:

 class Session { private $_session; public $maxTime; private $database; public function __construct(DBClass $database) { $this->database=$database; $this->maxTime['access'] = time(); $this->maxTime['gc'] = get_cfg_var('session.gc_maxlifetime'); session_set_save_handler(array($this,'_open'), array($this,'_close'), array($this,'_read'), array($this,'_write'), array($this,'_destroy'), array($this,'_clean') ); register_shutdown_function('session_write_close'); session_start(); ... } } 

User class (for more information about the current user):

 class User { private $username; private $role; private $session; function __construct($session) { $this->session=$session; ... } } 

Outwardly:

 $connection=new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE); $database=new DBClass($connection); $session=new Session($database); $user=new User($session); 

Is it correct?

+4
source share
1 answer

Yes. Now you enter the dependencies through the constructor, which provides less connectivity. Now you can easily replace these dependencies, for example. when UnitTesting you can replace them with Mocks.

You have some connection though using a specific DBClass like TypeHint instead of interface . Therefore, when you want to use another DBClass, you will need to call it DBClass. You could achieve a looser connection by using coding with an interface that must be implemented by specific classes.

To create only individual instances of the class (as specified in the comments), you can use Singleton (for example, suggested by Kevin Peno) or Factory to create and track if the instance was created yet. Or use a DI service container that is similar to Factory, but not the same. He creates and manages objects for you.

The Symfony Components library has a dependency injection container with excellent documentation and an introduction to how to further improve DI with service containers. Containers can also be used to limit instances. Check it.

+9
source

All Articles