Dependency Injection or instantiating database class object - php

this may seem like a broad question, but what are the practical uses of dependency injection vs instantiating the class inside a __construct() call?
I essentially instantiate my database object like this in classes that require it:
class Example {
private $db;
function __construct() {
$this->db = db::instance();
}
}
I've used dependency injection in the past and don't know if it's fine to simply share the resource, take the following for example from a Model.
Class ExampleModel extends Model {
function do_something() {
$user = new User($db);
$user->do_some_stuff();
}
}
So what would be more beneficial to use? Are there any performance related pros/cons? If you need more clarification to the questions, please ask.
There is a lot of positive & negative views on Dependency Injection:
Dependency Injection is EVIL
Dependency Injections Pros/Cons/Questions
Dependency Injection discourages object orientated programming
For anyone interested, this is what the db::instance() looks like:
public static function instance() {
if (!self::$instance) {
$config = get_config();
self::$instance = new self(
$config['database']['host'], $config['database']['user'], $config['database']['pass'], $config['database']['db']
);
}
return self::$instance;
}

Summarising my comments - for me, if you inject the dependency then Example doesn't need to know what the class you're injecting is. If you instantiate the class from within Example then you need to know exactly what the class is.
Is this a problem/benefit? Depends on you, your preferences and your application. I tend to prefer the more abstract approach.
For example, if you did the following:
class Example {
public function __construct(Injected $inj) {
$this->db = $inj;
}
}
... you can see that you type hint what you are expecting $inj to be. This can either be the type of the class that $inj directly is, or an interface that $inj implements - in which case you will know that $inj adheres to a set of instructions that you expect.
Take the following example:
interface Db {
public function fetch();
public function insert();
}
class MyDb implements Db {
public function fetch() {
// ...
}
public function insert() {
// ...
}
}
If you type hint the interface in your Example class, you don't need to know that $inj is a MyDb class, but that it implements Db - the important part is knowing that the class will follow a defined set of rules (an interface) e.g. that is will implement a fetch() and an insert() function. Nevermind the actual class - you just want the content.
class Example {
public function __construct(Db $inj) {
var_dump(get_class($inj)); // string(4) "MyDb"
}
}
This is all an example of injection and its benefits. The equivalent for direct instantiation would mean that your Example needs to know about MyDb:
class Example {
public function __construct() {
$this->db = new MyDb; // implements Db, but you need to know exactly
// what the class is
}
}
This method removes your flexibility for changing MyDb to YourDb without having to change the Example class.
Again, depends on your situation. If your application has the likelihood to change or has flexibility within components, you might want to use injection. If it's reasonably static then you could instantiate directly.
My final comment would be that when you are unit testing your code, it's much easier to mock an injected object than a directly instantiated one.

Related

How to avoid manually passing my $registry container into constructor of every new class I make?

I've been doing MVC for several months now, and I store everything in my $registry object. When I create a new class, I only ever pass the registry usually, but I'm having to constantly pass the $this->registry when creating a new class.
e.g.
class something
{
public function __construct($registry)
{
$this->registry = registry;
$this->db = $registry->db;
$this->user = $registry->user; // ......
}
public function something()
{
$class = new something_class($this->registry);
$class->do();
}
}
class something_class
{
public function __construct($registry)
{
$this->registry = $registry;
}
public function do()
{
echo 'Doing something ....';
}
}
My question is, how can I handle the passing of the registry to the new class behind the scenes (in this case when instantiating something_class) inside the registry class somehow? I'm absolutely convinced there is an easy way to do this, but I can't find anything related anywhere to what I'm looking for.
Here is my registry class:
<?php
class registry
{
protected $vars = array();
public function &__set($index, $value)
{
$this->vars[$index] = $value;
return $value;
}
public function &__get($index)
{
return $this->vars[$index];
}
}
This is all wrong. "Registry" is an anti-patter and what you are doing the is not dependency injection. You have found a way to fake global variables .. that's it.
As a start, please watch this lecture.
As for, how to correctly do what you want, there are two ways:
use a factory, that creates a class, using dependencies that you provided
use a dependency injection container, Auryn
To learn how you use a DI container, you will just have to consult the documentation. But I will explain the basics of factory, which is more of a DIY approach
A factory is an object, that is responsible for initializing other class. For example, you have a large set of classes, which require PDO as a dependency.
class Factory
{
private $pdo;
public function __construct(PDO $pdo) {
$this->pdo = $pdo;
}
public function create($name) {
return new $name($this->pdo);
}
}
If you use an instance of this class, it would let you create objects, which have the PDO already passed in as a dependency in a constructor:
$factory = new Factory(PDO($dsn, $user, $pass));
$user = $factory->create('User');
$document = $factory->create('Doc');
And as an added benefit, this setup would let bot the User class instance and the Doc class instance to share the same PDO object.
It's best practice to have your classes or components not be dependent on your container. Let your container do the injection of dependencies.
Here's an example that uses Container from The League of Extraordinary Packages and shows class B being dependent on A:
<?php
$container = new League\Container\Container();
$container->add('b', function () {
$a = new A('foo');
$b = new B($a);
return $b;
});
var_dump($container->get('b')->getValueFromA()); // Outputs "foo"
class A
{
private $value;
public function __construct($value)
{
$this->value = $value;
}
public function getValue()
{
return $this->value;
}
}
class B
{
public function __construct(A $a)
{
$this->a = $a;
}
public function getValueFromA()
{
return $this->a->getValue();
}
}
Each class you write should only be coupled to its direct dependencies. If possible, the use of interfaces is highly recommended for further decoupling.
Please see this Stackoverflow question for more information around the differences between a registry and a DI container. Using a registry is considered an anti-pattern and should be avoided.
Your $registry class is what's called a Service Locator pattern. It is useful in some contexts, but it has a high potential for being abused, especially when you inject the service locator into your class.
Dependency Injection is supposed to expose (show) all the objects that your class uses (or depends on). Injecting $registry in your class instead hides the dependencies, and this is why it is an anti-pattern. Also, it creates a burden for you as you have to pass it everywhere, you might as well make it a global to make it easier (this will also answer your question). But better tools are available.
Consider your class like so:
Note the use of dependency injection of $db and $user into constructor of something class. Now it is more clear what your class needs to work.
Also note the use of dependency injection container in this case Auryn to create a class for you.
//in your bootstrap or part of your framework
$injector = new Auryn\Injector();
$class = $injector->make('something_class');
//Your own code:
class something
{
public function __construct(Database $db, User $user)
{
$this->db = $db;
$this->user = $user;
}
public function something(something_class $class)
{
$class->do();
}
}
You can also use Auryn to do what you want to do to call the Registry class. But you will soon find that Auryn is a better more robust version of your Registry class and one that forces you to use better dependency-injection techniques for Auryn to work as intended.
Basic point is that your own application (all of your application's classes) best not be aware of any container. Because what containers do is they hide dependencies from your classes. It remains however as acceptable to use containers as part of a framework. Let your framework handle containers, but you focus on your own classes, without calling containers unless those containers are used as part of your framework to wire up your application.

PHP Dependency Injection

I'm trying to get my head around Dependency Injection and I understand it, for the most part.
However, say if, for some reason, one of my classes was dependent on several classes, instead of passing all of these to this one class in the constructor, is there a better, more sensible method?
I've heard about DI Containers, is this how I would go about solving this problem? Where should I start with this solution? Do I pass the dependencies to my DIC, and then pass this to the class that needs these dependencies?
Any help that would point me in the right direction would be fantastic.
Dependency Injection !== DIC
People should really stop confusing them. Dependency Injection is idea that comes from Dependency Inversion principle.
The DIC is "magic cure", which promises to let you use dependency injection, but in PHP is usually implemented by breaking every other principle of object oriented programming. The worst implementations tend to also attach it all to global state, via static Registry or Singleton.
Anyway, if your class depends on too many other classes, then in general , it signifies a design flaw in the class itself. You basically have a class with too many reasons to change, thus, breaking the Single Responsibility principle.
In this case, then dependency injection container will only hide the underlaying design issues.
If you want to learn more about Dependency Injection, i would recommend for you to watch the "Clean Code Talks" on youtube:
The Clean Code Talks - Don't Look For Things!
The Clean Code Talks - "Global State and Singletons"
If you have several dependencies to deal with, then yes a DI container can be the solution.
The DI container can be an object or array constructed of the various dependent object you need, which gets passed to the constructor and unpacked.
Suppose you needed a config object, a database connection, and a client info object passed to each of your classes. You can create an array which holds them:
// Assume each is created or accessed as a singleton, however needed...
// This may be created globally at the top of your script, and passed into each newly
// instantiated class
$di_container = array(
'config' = new Config(),
'db' = new DB($user, $pass, $db, $whatever),
'client' = new ClientInfo($clientid)
);
And your class constructors accept the DI container as a parameter:
class SomeClass {
private $config;
private $db;
private $client;
public function __construct(&$di_container) {
$this->config = $di_container['config'];
$this->db = $di_container['db'];
$this->client = $di_container['client'];
}
}
Instead of an array as I did above (which is simple), you might also create the DI container as an class itself and instantiate it with the component classes injected into it individually. One benefit to using an object instead of an array is that by default it will be passed by reference into the classes using it, while an array is passed by value (though objects inside the array are still references).
Edit
There are some ways in which an object is more flexible than an array, although more complicated to code initially.
The container object may also create/instantiate the contained classes in its constructor as well (rather than creating them outside and passing them in). This can save you some coding on each script that uses it, as you only need to instantiate one object (which itself instantiates several others).
Class DIContainer {
public $config;
public $db;
public $client;
// The DI container can build its own member objects
public function __construct($params....) {
$this->config = new Config();
// These vars might be passed in the constructor, or could be constants, or something else
$this->db = new DB($user, $pass, $db, $whatever);
// Same here - the var may come from the constructor, $_SESSION, or somewhere else
$this->client = new ClientInfo($clientid);
}
}
I've wrote an article about this problem.
The ideea is to use a combination of abstract factory and dependency injection to achieve transparent dependency resolving of (possible nested) dependencies. I will copy/paste here the main code snippets:
namespace Gica\Interfaces\Dependency;
interface AbstractFactory
{
public function createObject($objectClass, $constructorArguments = []);
}
The abstract factory implementation is:
namespace Gica\Dependency;
class AbstractFactory implements \Gica\Interfaces\Dependency\AbstractFactory, \Gica\Interfaces\Dependency\WithDependencyInjector
{
use WithDependencyInjector;
/**
* #param string $objectClass
* #param array $constructorArguments
* #return object instanceof $class
*/
public function createObject($objectClass, $constructorArguments = [])
{
$instance = new $objectClass(...$constructorArguments);
$this->getDependencyInjector()->resolveDependencies($instance);
return $instance;
}
}
The dependency injector is this:
namespace Gica\Dependency;
class DependencyInjector implements \Gica\Interfaces\Dependency\DependencyInjector
{
use \Gica\Traits\WithDependencyContainer;
public function resolveDependencies($instance)
{
$sm = $this->getDependencyInjectionContainer();
if ($instance instanceof \Gica\Interfaces\WithAuthenticator) {
$instance->setAuthenticator($sm->get(\Gica\Interfaces\Authentication\Authenticator::class));
}
if ($instance instanceof \Gica\Interfaces\WithPdo) {
$instance->setPdo($sm->get(\Gica\SqlQuery\Connection::class));
}
if ($instance instanceof \Gica\Interfaces\Dependency\WithAbstractFactory) {
$instance->setAbstractFactory($sm->get(\Gica\Interfaces\Dependency\AbstractFactory::class));
}
//... all the dependency declaring interfaces go below
}
}
The dependency container is the standard one.
The client code could look something like this:
$abstractFactory = $container->get(\Gica\Interfaces\Dependency\AbstractFactory::class);
$someHelper = $abstractFactory->createObject(\Web\Helper\SomeHelper::class);
echo $someHelper->helpAction();
Notice that dependencies are hidden, and we can focus on the main bussiness. My client code doesn't care or know that $someHelper need an Authenticator or that helpAction need an SomeObject to do its work;
In the background a lot of things happen, a lot of dependencies are detected, resolved and injected.
Notice that I don't use the new operator to create $someObject. The responsability of actual creation of the object is passed to the AbstractFactory
P.S. Gica is my nickname :)
I recommend you to use Singltones or Mutlitones. In these cases you will be always able to get objects via static class' methods.
The other way (couldn't find a correct pattern name, but it could be Registry) is to use one global static object to store multiple objects' instances. E.g. (simplified code, without any checks):
class Registry {
private static $instances = array();
public static function add($k, $v) {
$this->instances[$k] = $v;
}
public static function get($k) {
return $this->instances[$k];
}
}
class MyClass {
public function __construct() {
Registry::add('myclass', $this);
}
}

Sharing objects between multiple classes using base class

This article is similar to my needs, but I'm more curious about a specific solution to it, and if it's a good or bad idea to do it. Sharing objects between PHP classes
Say, like in the link above, I have an object I want to pass to multiple classes, say a $db object.
Instead of using dependency injection and passing it to each method's constructor, is it ever a good idea to let all the classes extend a Base class, that stores the $db object as a property?
For example:
abstract class Base {
protected static $_db;
public function setDatabase( Database $db ) {
$this->_db = $db;
}
public function getDatabase() {
return $this->_db;
}
}
class SomeClass extends Base {
public function doStuff() {
$result = $this->getDatabase()->query(.....);
}
}
Which would mean all classes that extend Base need not worry about grabbing/checking/setting the $db themselves, as they'd already have that object as a property as soon as the class is defined.
I know dependency injection is the usual way to go, but is this ever a viable solution?
Thanks!
You still have to set the db on each instance of the class - setting it on one instance doesnt set it on all instances... unless of course its a static property.
That is perfectly fine. I have used it before and never ran into any issues.

How do I instantiate my database object, to be used in other classes?

I've encountered an architectural issue with my application. I've rolled my own (very basic) MVC, and one of my models is a database object: class MySQLDatabase { }
There's a number of places in which I'd want to use my database object, without creating duplicate instances. Inside my controller, I have declared public $db; and within the __construct { } I have $this->db = new MySQLDatabase;
Question:
How do I use $db within my other classes--they're all instantiated within the controller's __construct { } as well... would I declare global $db at the top of all my classes that require database connectivity?
I'm used to global variables being declared in the global scope as regular variables, and then using the global keyword to reference the global scope... I'm not sure if that applies to variables declared within a class (my controller.)
I would stay away from using globals or the Singleton pattern (which is essentially a global anyway), and try and find some alternatives. Additionally you are talking about a database connection, by using the Singleton pattern you are saying that there will never be more than one database connection, whilst that is generally true in smaller applications, as they grow larger you won't be able to accomodate multiple connections.
Once you make something global then you lose the automatic contraints of where it can be used/modified. Using MVC a view shouldn't be used for anything other than to display data, by using a global/singleton it is up to the developer to not make use of the globals. Whereas with a different design they don't have that option.
You mentioned you've created your own MVC framework, so I imagine the classes you want to use it in are your models? Correct me if they are anywhere else.
If your models extend from a common base class then you could pass your database object to that class as a static variable which can be assigned to any new instances in the construct or using a factory method in the factory method.
This isn't to say that globals or singletons should be avoided at all costs, but definitely try consider the alternatives that could lead to a neater design.
Here's some reading on the Singleton pattern if you're interested:
Patterns I Hate #1: Singleton
Why Singletons are Evil
Singleton Considered Stupid
Use your singletons wisely
There are many more out there...
If I understand correctly you have a single controller that instantiates the database object and it also takes care of instantiating other classes. If so, you could implement some form of dependency injection either passing the db object in the constructor of the other classes or creating a setter method.
A good blog article on the subject:
http://www.potstuck.com/2009/01/08/php-dependency-injection/
I Think you going about this the wrong way, you should not be performaing quesries to the database from you controller.
this means that the below is invalid.
class ControllerIndex extends Controller
{
public function index()
{
$this->db->selectAll("table");
}
}
There should be a layer that separates your controller from your database interface, this is where a Model comes in.
You should have a models folder that contain classes for actions taken such as users,posts,logging etc.
class Users_Model extends Model
{
public function getUser($id)
{
}
}
The model class should be part of your system core, and should extend your Database Class, this way within your main controller you should be loading the models via the ModelLoader class.
for example:
class ModelLoader
{
private $models = array();
public function __get($model)
{
//load (/application/models/?.php) and initiate it here
//Storing it in models array above
}
}
Then in your main controller:
class Controller
{
private $model;
public function __construct()
{
$this->model = new ModelLoader;
}
}
this way your bringing your loader into scope for the child controller:
class Controller_index extends Controller
{
public function index()
{
$user = $this->model->users->getUser(22);
}
}
Hope this helps!
I think what you need here is a singleton for you Database object :)
See here for more details : http://en.wikipedia.org/wiki/Singleton_pattern
Edit with sample singleton for php :
<?php
class UniqueObject {
private $_uniq = null;
//private cause you don't want to instanciate the classic way
private function __construct() {
//...
}
//check if unique object exists or not, then return it
public static function uniq() {
if(!self::$_uniq)
self::$_uniq = new UniqueObject();
return self::$_uniq;
}
}
//call your unique object whenever you need it
UniqueObject::uniq();
?>
(it's late, i hope i didn't do any mistake :))
Don't use singletons. It's much better to explicitly pass around data. For example:
abstract class Controller {
private static $conn; // could be an array for multiple connections
final protected function getDBConnection() {
if (!$this->conn) {
$this->conn = new DBConnection();
}
return $this->conn;
}
abstract public function process(Request $r);
}
class HomePageController extends Controller {
public function process(Request $r) {
$results = $this->getDBConnection()->query('SELECT stuff FROM foo;');
// do stuff with $results
}
}
You could also have an explicit model object you pass around, e.g. the one that represents the user, but that may be overkill for your project.
You'll need to use a singleton pattern. They give examples in the php docs
<?php
class Example
{
// Hold an instance of the class
private static $instance;
// A private constructor; prevents direct creation of object
private function __construct()
{
echo 'I am constructed';
}
// The singleton method
public static function singleton()
{
if (!isset(self::$instance)) {
$c = __CLASS__;
self::$instance = new $c;
}
return self::$instance;
}
// Example method
public function bark()
{
echo 'Woof!';
}
// Prevent users to clone the instance
public function __clone()
{
trigger_error('Clone is not allowed.', E_USER_ERROR);
}
}
?>
http://php.net/manual/en/language.oop5.patterns.php

Dependency injection when you have no control over instantiation and usage

How is it done?
I have a Model class that is the parent to many sub-classes, and that Model depends on a database connection and a caching mechanism.
Now, this is where it starts getting troublesome: I have no control over how each object gets instantiated or used, but I have control over methods that get used by the sub-classes.
Currently I have resorted to using static methods and properties for dependency injection, as such:
class Model
{
private static $database_adapter;
private static $cache_adapter;
public static function setDatabaseAdapter(IDatabaseAdapter $databaseAdapter)
{
self::$databaseAdapter = $databaseAdapter;
}
public static function setCacheAdapter(ICacheAdapter $cacheAdapter)
{
self::$cacheAdapter = $cacheAdapter;
}
}
Which has worked out well, but it feels dirty (it creates a global state for all Models).
I have considered the factory pattern, but that removes the control of the instantiation from the sub-classes (how do I instantiate an object with a variable number of parameters in it's constructor?).
Now I am at a loss. Any help would be appreciated.
As far as I know this is a perfectly acceptable alternative. Another possibility suggested by Sebastian Bergmann, the creator of PHPUnit, is to have a $testing static property. You can read his recent article regarding the Testing of Singletons. It sounds like you have similar issues.
You're solution would be fine for setting default adapters, but I'd add a way for the individual models to have a different adapter. Consider this:
abstract class Model {
protected $_database_adapter;
protected $_default_database_adapter;
public function getDatabaseAdapter() {
if(!$this->_database_adapter) {
if(self::$_default_database_adapter) {
$this->_database_adapter = self::$_default_database_adapter;
} else {
throw new Exception("No adapter set yet");
}
}
return $this->_database_adapter;
}
public function setDatabaseAdapter(IDatabaseAdapter $databaseAdapter) {
$this->_database_adapter = $databaseAdapter;
}
public static function setDefaultDatabaseAdapter(IDatabaseAdapter $databaseAdapter) {
self::$_default_database_adapter = $databaseAdapter;
}
}
Of course you could extract all static methods/properties into a Registry, Container or anything else as central.
For example, perhaps you don't want to collect data from the same database host over your whole application. Then your original script would look like the following:
Model::setDatabaseAdapter($default);
$my_model->query('....');
Model::setDatabaseAdapter($another_adapter);
$my_other_model->query('....');
Model::setDatabaseAdapter($default);
which is awfully alike:
mysql_select_db('default_db');
mysql_query('...');
mysql_select_db('other_db');
mysql_query('...');
mysql_select_db('default_db');

Categories