Dependency Injection: pulling required components when they are actually needed - php

The gist behind DI is to relieve a class from creating and preparing objects it depends on and pushing them in. This sounds very reasonable, but sometimes a class does not need all the objects, that are being pushed into it to carry out its function. The reason behind this is an "early return" that happens upon invalid user input or an exception thrown by one of the required objects earlier or the unavailability of a certain value necessary to instantiate an object until a block of code runs.
More practical examples:
injecting a database connection object that will never be used, because the user data does not pass validation (provided that no triggers are used to validate this data)
injecting excel-like objects (PHPExcel e.g.) that collect input (heavy to load and instantiate because a whole library is pulled in and never used, because validation throws an exception earlier than a write occurs)
a variable value that is determined within a class, but not the injector at runtime; for instance, a routing component that determines the controller (or command) class and method that should be called based on user input
although this might be a design problem, but a substantial service-class, that depends on a lot of components, but uses only like 1/3 of them per request (the reason, why i tend to use command classes instead of controllers)
So, in a way pushing in all necessary components contradicts "lazy-loading" in the way that some components are created and never used, that being a bit unpractical and impacting performance. As far as PHP is concerned - more files are loaded, parsed and compiled. This is especially painful, if the objects being pushed in have their own dependencies.
i see 3 ways around it, 2 of which don't sound very well:
injecting a factory
injecting the injector (an anti-pattern)
injecting some external function, that gets called from within the
class once a relevant point is reached (smtg like "retrieve a
PHPExcel instance once data validation finished"); this is what i
tend to use due to its flexibility
The question is what's the best way of dealing with such situations / what do you guys use?
UPDATE:
#GordonM here are the examples of 3 approaches:
//inject factory example
interface IFactory{
function factory();
}
class Bartender{
protected $_factory;
public function __construct(IFactory $f){
$this->_factory = $f;
}
public function order($data){
//validating $data
//... return or throw exception
//validation passed, order must be saved
$db = $this->_factory->factory(); //! factory instance * num necessary components
$db->insert('orders', $data);
//...
}
}
/*
inject provider example
assuming that the provider prepares necessary objects
(i.e. injects their dependencies as well)
*/
interface IProvider{
function get($uid);
}
class Router{
protected $_provider;
public function __construct(IProvider $p){
$this->_provider = $p;
}
public function route($str){
//... match $str against routes to resolve class and method
$inst = $this->_provider->get($class);
//...
}
}
//inject callback (old fashion way)
class MyProvider{
protected $_db;
public function getDb(){
$this->_db = $this->_db ? $this->_db : new mysqli();
return $this->_db;
}
}
class Bartender{
protected $_db;
public function __construct(array $callback){
$this->_db = $callback;
}
public function order($data){
//validating $data
//... return or throw exception
//validation passed, order must be saved
$db = call_user_func_array($this->_db, array());
$db->insert('orders', $data);
//...
}
}
//the way it works under the hood:
$provider = new MyProvider();
$db = array($provider, 'getDb');
new Bartender($db);
//inject callback (the PHP 5.3 way)
class Bartender{
protected $_db;
public function __construct(Closure $callback){
$this->_db = $callback;
}
public function order($data){
//validating $data
//... return or throw exception
//validation passed, order must be saved
$db = call_user_func_array($this->_db, array());
$db->insert('orders', $data);
//...
}
}
//the way it works under the hood:
static $conn = null;
$db = function() use ($conn){
$conn = $conn ? $conn : new mysqli();
return $conn;
};
new Bartender($db);

I've been thinking about this problem a lot lately in planning of a major project that I want to do as right as humanly possible (stick to LoD, no hard coded dependencies, etc). My first thought was the "Inject a factory" approach as well, but I'm not sure that's the way to go. The Clean Code talks from Google made the claim that if you reach through an object to get the object you really want then you're violating the LoD. That would seem to rule out the idea of injecting a factory, because you have to reach through the factory to get what you really want. Maybe I've missed some point there that makes it okay, but until I know for sure I'm pondering other approaches.
How do you do the function injection? I'd imagine you're passing in a callback that does the instantiation of the object you want, but a code example would be nice.
If you could update your question with code examples of how you do the three styles you mentioned it might be useful. I'm especially keen to see "injecting the injector" even if it is an antipattern.

One idea that did occur was that of a proxy object. It implements the same interface(s) as the actual object you want to pass in, but instead of implementing anything it just holds an instance of the real class and forwards method calls on to it.
interface MyInterface
{
public function doFoo ();
public function isFoo ();
// etc
}
class RealClass implements MyInterface
{
public function doFoo ()
{
return ('Foo!');
}
public function isFoo ()
{
return ($this -> doFoo () == 'Foo!'? true: false);
}
// etc
}
class RealClassProxy implements MyInterface
{
private $instance = NULL;
/**
* Do lazy instantiation of the real class
*
* #return RealClass
*/
private function getRealClass ()
{
if ($this -> instance === NULL)
{
$this -> instance = new RealClass ();
}
return $this -> instance;
}
public function doFoo ()
{
return $this -> getRealClass () -> doFoo ();
}
public function isFoo ()
{
return $this -> getRealClass () -> isFoo ();
}
// etc
}
Because the proxy has the same interface as the real class, you can pass it as an argument to any function/method that type hints for the interface. The Liskov Substitution Principle holds for the proxy because it responds to all the same messages as the real class and returns the same results (the interface enforces this, at least for method signitures). However, the real class doesn't get instantiated unless a message actually gets sent to the proxy, which does lazy instantiation of the real class behind the scenes.
function sendMessageToRealClass (MyInterface $instance)
{
$instance -> doFoo ();
}
sendMessageToRealClass (new RealClass ());
sendMessageToRealClass (new RealClassProxy ());
There is an extra layer of indirection involved with the proxy object, which obviously means that there is a small performance hit for every method call you make. However, it does allow you to do lazy instantiation, so you can avoid instantiating classes you don't need. Whether this is worth it depends on the cost of instantiating the real object versus the cost of the extra layer of indirection.
EDIT: I had originally written this answer with the idea of subclassing the real object so you could use the technique with objects that don't implement any interfaces such as PDO. I had originally thought that interfaces were the correct way to do this but I wanted an approach that didn't rely on the class being tied to an interface. On reflection that was a big mistake so I've updated the answer to reflect what I should have done in the first place. This version does mean, however, that you can't directly apply this technique to classes with no associated interface. You'll have to wrap such classes in another class that does provide an interface for the proxy approach to be viable, meaning yet another layer of indirection.

If you want to implement lazy loading you basically have two way to do it (as you have already written in the topic):
instead of injecting an instance of object you might need, you inject a Factory or a Builder. The difference between them is that instance of Builder is made for returning one type of object (maybe with different setups), while Factory makes different types of instances ( with same lifetime and/or implementing same interface ).
utilize anonymous function which will return you an instance. That would look something like this:
$provider = function() {
return new \PDO('sqlite::memory:');
};
Only when you call this anonymous function, the instance of PDO is created and connection to database established.
What I usually do in my code is combine both. You can equip the Factory with such provider. This, for example, lets you have a single connection for all the objects which where created by said factory, and the connection is create only, when you first time ask an instance from Factory.
The other way to combine both methods (which i have not used, though) would be to create full blow Provider class, which in constructor accepts an anonymous function. Then the factory could pass around this same instance of Provider and the expensive object (PHPExcel, Doctrine, SwiftMailer or some other instance) is only created once a Product from that Factory first time turns to the Provider (couldn't come up with better name to describe all objects created by same factory) and requests it. After that, this expensive object is shared between all Products of Factory.
... my 2 cents

I chose lazy-injection (i.e. injecting a Proxy class):
class Class1 {
/**
* #Inject(lazy=true)
* #var Class2
*/
private $class2;
public function doSomething() {
// The dependency is loaded NOW
return $this->class2->getSomethingElse();
}
Here, the dependency (class2) is not injected directly: a proxy class is injected. Only when the proxy class is used that the dependency is loaded.
This is possible in PHP-DI (dependency injection framework).
Disclaimer: I work in this project

Related

Alternatives to static methods in a framework PHP

Lately I have been trying to create my own PHP framework, just to learn from it (As we may look into some bigger and more robust framework for production). One design concept I currently have, is that most core classes mainly work on static functions within classes.
Now a few days ago, I've seen a few articles about "Static methods are death to testability". This concerned me as.. yeah.. my classes contain mostly static methods.. The main reason I was using static methods is that a lot of classes would never need more than one instance, and static methods are easy to approach in the global scope. Now I'm aware that static methods aren't actually the best way to do things, I'm looking for a better alternative.
Imagine the following code to get a config item:
$testcfg = Config::get("test"); // Gets config from "test"
echo $testcfg->foo; // Would output what "foo" contains ofcourse.
/*
* We cache the newly created instance of the "test" config,
* so if we need to use it again anywhere in the application,
* the Config::get() method simply returns that instance.
*/
This is an example of what I currently have. But according to some articles, this is bad.
Now, I could do this the way how, for example, CodeIgniter does this, using:
$testcfg = $this->config->get("test");
echo $testcfg->foo;
Personally, I find this harder to read. That's why I would prefer another way.
So in short, I guess I need a better approach to my classes. I would not want more than one instance to the config class, maintain readability and have easy access to the class. Any ideas?
Note that I'm looking for some best practice or something including a code sample, not some random ideas. Also, if I'm bound to a $this->class->method style pattern, then would I implement this efficiently?
In response to Sébastien Renauld's comments: here's an article on Dependency Injection (DI) and Inversion of Control (IoC) with some examples, and a few extra words on the Hollywood principle (quite important when working on a framework).
Saying your classes won't ever need more than a single instance doesn't mean that statics are a must. Far from it, actually. If you browse this site, and read through PHP questions that deal with the singleton "pattern", you'll soon find out why singletons are a bit of a no-no.
I won't go into the details, but testing and singletons don't mix. Dependency injection is definitely worth a closer look. I'll leave it at that for now.
To answer your question:
Your exaple (Config::get('test')) implies you have a static property in the Config class somewhere. Now if you've done this, as you say, to facilitate access to given data, imagine what a nightmare it would be to debug your code, if that value were to change somewhere... It's a static, so change it once, and it's changed everywhere. Finding out where it was changed might be harder than you anticipated. Even so, that's nothing compared to the issues someone who uses your code will have in the same situation.
And yet, the real problems will only start when that person using your code wants to test whatever it is he/she made: If you want to have access to an instance in a given object, that has been instantiated in some class, there are plenty of ways to do so (especially in a framework):
class Application
{//base class of your framework
private $defaulDB = null;
public $env = null;
public function __construct($env = 'test')
{
$this->env = $env;
}
private function connectDB(PDO $connection = null)
{
if ($connection === null)
{
$connection = new PDO();//you know the deal...
}
$this->defaultDB = $connection;
}
public function getDB(PDO $conn = null)
{//get connection
if ($this->defaultDB === null)
{
$this->connectDB($conn);
}
return $this->defaultDB;
}
public function registerController(MyConstroller $controller)
{//<== magic!
$controller->registerApplication($this);
return $this;
}
}
As you can see, the Application class has a method that passes the Application instance to your controller, or whatever part of your framework you want to grant access to scope of the Application class.
Note that I've declared the defaultDB property as a private property, so I'm using a getter. I can, if I wanted to, pass a connection to that getter. There's a lot more you can do with that connection, of course, but I can't be bothered writing a full framework to show you everything you can do here :).
Basically, all your controllers will extend the MyController class, which could be an abstract class that looks like this:
abstract class MyController
{
private $app = null;
protected $db = null;
public function __construct(Application $app = null)
{
if ($app !== null)
{
return $this->registerApplication($app);
}
}
public function registerApplication(Application $app)
{
$this->app = $app;
return $this;
}
public function getApplication()
{
return $this->app;
}
}
So in your code, you can easily do something along the lines of:
$controller = new MyController($this);//assuming the instance is created in the Application class
$controller = new MyController();
$controller->registerApplication($appInstance);
In both cases, you can get that single DB instance like so:
$controller->getApplication()->getDB();
You can test your framework with easily by passing a different DB connection to the getDB method, if the defaultDB property hasn't been set in this case. With some extra work you can register multiple DB connections at the same time and access those at will, too:
$controller->getApplication->getDB(new PDO());//pass test connection here...
This is, by no means, the full explanation, but I wanted to get this answer in quite quickly before you end up with a huge static (and thus useless) codebase.
In response to comments from OP:
On how I'd tackle the Config class. Honestly, I'd pretty much do the same thing as I'd do with the defaultDB property as shown above. But I'd probably allow for more targeted control on what class gets access to what part of the config:
class Application
{
private $config = null;
public function __construct($env = 'test', $config = null)
{//get default config path or use path passed as argument
$this->config = new Config(parse_ini_file($config));
}
public function registerController(MyController $controller)
{
$controller->setApplication($this);
}
public function registerDB(MyDB $wrapper, $connect = true)
{//assume MyDB is a wrapper class, that gets the connection data from the config
$wrapper->setConfig(new Config($this->config->getSection('DB')));
$this->defaultDB = $wrapper;
return $this;
}
}
class MyController
{
private $app = null;
public function getApplication()
{
return $this->app;
}
public function setApplication(Application $app)
{
$this->app = $app;
return $this;
}
//Optional:
public function getConfig()
{
return $this->app->getConfig();
}
public function getDB()
{
return $this->app->getDB();
}
}
Those last two methods aren't really required, you could just as well write something like:
$controller->getApplication()->getConfig();
Again, this snippet is all a bit messy and incomplete, but it does go to show you that you can "expose" certain properties of one class, by passing a reference to that class to another. Even if the properties are private, you can use getters to access them all the same. You can also use various register-methods to control what it is the registered object is allowed to see, as I've done with the DB-wrapper in my snippet. A DB class shouldn't deal with viewscripts and namespaces, or autoloaders. That's why I'm only registering the DB section of the config.
Basically, a lot of your main components will end up sharing a number of methods. In other words, they'll end up implementing a given interface. For each main component (assuming the classic MVC pattern), you'll have one abstract base-class, and an inheritance chain of 1 or 2 levels of child classes: Abstract Controller > DefaultController > ProjectSpecificController.
At the same time, all of these classes will probably expect another instance to be passed to them when constructed. Just look at the index.php of any ZendFW project:
$application = new Zend_Application(APPLICATION_ENV);
$application->bootstrap()->run();
That's all you can see, but inside the application, all other classes are being instantiated. That's why you can access neigh on everything from anywhere: all classes have been instantiated inside another class along these lines:
public function initController(Request $request)
{
$this->currentController = $request->getController();
$this->currentController = new $this->currentController($this);
return $this->currentController->init($request)
->{$request->getAction().'Action'}();
}
By passing $this to the constructor of a controller class, that class can use various getters and setters to get to whatever it needs... Look at the examples above, it could use getDB, or getConfig and use that data if that's what it needs.
That's how most frameworks I've tinkered or worked with function: The application is kicks into action and determines what needs to be done. That's the Hollywood-principle, or Inversion of Control: the Application is started, and the application determines what classes it needs when. In the link I provided I believe this is compared to a store creating its own customers: the store is built, and decides what it wants to sell. In order to sell it, it will create the clients it wants, and provide them with the means they need to purchase the goods...
And, before I forget: Yes, all this can be done without a single static variable, let alone function, coming into play. I've built my own framework, and I've never felt there was no other way than to "go static". I did use the Factory pattern at first, but ditched it pretty quickly.
IMHO, a good framework is modular: you should be able to use bits of it (like Symfony's components), without issues. Using the Factory pattern makes you assume too much. You assume class X will be available, which isn't a given.
Registering those classes that are available makes for far more portable components. Consider this:
class AssumeFactory
{
private $db = null;
public function getDB(PDO $db = null)
{
if ($db === null)
{
$config = Factory::getConfig();//assumes Config class
$db = new PDO($config->getDBString());
}
$this->db = $db;
return $this->db;
}
}
As opposed to:
class RegisteredApplication
{//assume this is registered to current Application
public function getDB(PDO $fallback = null, $setToApplication = false)
{
if ($this->getApplication()->getDB() === null)
{//defensive
if ($setToApplication === true && $fallback !== null)
{
$this->getApplication()->setDB($fallback);
return $fallback;//this is current connection
}
if ($fallback === null && $this->getApplication()->getConfig() !== null)
{//if DB is not set #app, check config:
$fallback = $this->getApplication()->getConfig()->getSection('DB');
$fallback = new PDO($fallback->connString, $fallback->user, $fallback->pass);
return $fallback;
}
throw new RuntimeException('No DB connection set #app, no fallback');
}
if ($setToApplication === true && $fallback !== null)
{
$this->getApplication()->setDB($fallback);
}
return $this->getApplication()->getDB();
}
}
Though the latter version is slightly more work to write, it's quite clear which of the two is the better bet. The first version just assumes too much, and doesn't allow for safety-nets. It's also quite dictatorial: suppose I've written a test, and I need the results to go to another DB. I therefore need to change the DB connection, for the entire application (user input, errors, stats... they're all likely to be stored in a DB).
For those two reasons alone, the second snippet is the better candidate: I can pass another DB connection, that overwrites the application default, or, if I don't want to do that, I can either use the default connection, or attempt to create the default connection. Store the connection I just made, or not... the choice is entirely mine. If nothing works, I just get a RuntimeException thrown at me, but that's not the point.
Magic methods would help you: see the examples about __get() and __set()
You should also take a look at namespaces: it may help you to get rid of some classes with static methods only.

Design Patterns: How to create database object/connection only when needed?

I've a simple application, say it has some classes and an "extra" one that handles database requests. Currently i'm creating the database object everytime the app is used, but in some cases there's no need for a database connection. I'm doing it like this (PHP btw):
$db = new Database();
$foo = new Foo($db); // passing the db
But sometimes the $foo object does not need db access, as only methods without database actions are called. So my question is: What's the professional way to handle situations like this / how to create the db connection/object only when needed ?
My goal is to avoid unnecessary database connections.
Note: Although the direct answer to ops question, "when can I only create / connect to the database when required and not on every request" is inject it when you need it, simply saying that is not helpful. I'm explaining here how you actually go about that correctly, as there really isn't a lot of useful information out there in a non-specific-framework context to help in this regard.
Updated: The 'old' answer to this question can be see below. This encouraged the service locator pattern which is very controversial and to many an 'anti-pattern'. New answer added with what I've learned from researching. Please read the old answer first to see how this progressed.
New Answer
After using pimple for a while, I learned much about how it works, and how it's not actually that amazing after all. It's still pretty cool, but the reason it's only 80 lines of code is because it basically allows the creation of an array of closures. Pimple is used a lot as a service locator (because it's so limited in what it can actually do), and this is an "anti-pattern".
Firstly, what is a service locator?
The service locator pattern is a design pattern used in software development to encapsulate the processes involved in obtaining a service with a strong abstraction layer. This pattern uses a central registry known as the "service locator" which on request returns the information necessary to perform a certain task.
I was creating pimple in the bootstrap, defining dependencies, and then passing this container to each and every single class I instantiated.
Why is a service locator bad?
What's the problem with this you say? The main problem is that this approach hides dependencies from the class. So if a developer is coming to update this class and they haven't seen it before, they're going to see a container object containing an unknown amount of objects. Also, testing this class is going to be a bit of a nightmare.
Why did I do this originally? Because I thought that after the controller is where you start doing your dependency injection. This is wrong. You start it straight away at the controller level.
If this is how things work in my application:
Front Controller --> Bootstrap --> Router --> Controller/Method --> Model [Services|Domain Objects|Mappers] --> Controller --> View --> Template
...then the dependency injection container should start working right away at the first controller level.
So really, if I were to still use pimple, I would be defining what controllers are going to be created, and what they need. So you would inject the view and anything from the model layer into the controller so it can use it. This is Inversion Of Control and makes testing much easier. From the Aurn wiki, (which I'll talk about soon):
In real life you wouldn't build a house by transporting the entire hardware store (hopefully) to the construction site so you can access any parts you need. Instead, the foreman (__construct()) asks for the specific parts that will be needed (Door and Window) and goes about procuring them. Your objects should function in the same way; they should ask only for the specific dependencies required to do their jobs. Giving the House access to the entire hardware store is at best poor OOP style and at worst a maintainability nightmare. - From the Auryn Wiki
Enter Auryn
On that note, I'd like to introduce you to something brilliant called Auryn, written by Rdlowrey that I was introduced to over the weekend.
Auryn 'auto-wires' class dependencies based on the class constructor signature. What this means that, for each class requested, Auryn finds it, figures out what it needs in the constructor, creates what it needs first and then creates an instance of the class you asked for originally. Here's how it works:
The Provider recursively instantiates class dependencies based on the parameter type-hints specified in their constructor method signatures.
...and if you know anything about PHP's reflection, you'll know some people call it 'slow'. So here's what Auryn does about that:
You may have heard that "reflection is slow". Let's clear something up: anything can be "too slow" if you're doing it wrong. Reflection is an order of magnitude faster than disk access and several orders of magnitude faster than retrieving information (for example) from a remote database. Additionally, each reflection offers the opportunity to cache the results if you're worried about speed. Auryn caches any reflections it generates to minimize the potential performance impact.
So now we've skipped the "reflection is slow" argument, here's how I've been using it.
How I use Auryn
I make Auryn part of my autoloader. This is so that when a class is asked for, Auryn can go away and read the class and it's dependencies, and it's dependencies' dependencies (etc), and return them all into the class for instantiation. I create the Auyrn object.
$injector = new \Auryn\Provider(new \Auryn\ReflectionPool);
I use a Database Interface as a requirement in the constructor of my database class. So I tell Auryn which concrete implementation to use (this is the part you change if you want to instantiate a different type of database, at a single point in your code, and it'll all still work).
$injector->alias('Library\Database\DatabaseInterface', 'Library\Database\MySQL');
If I wanted to change to MongoDB and I'd written a class for it, I'd simple change Library\Database\MySQL to Library\Database\MongoDB.
Then, I pass the $injector into my router, and when creating the controller / method, this is where the dependencies are automatically resolved.
public function dispatch($injector)
{
// Make sure file / controller exists
// Make sure method called exists
// etc...
// Create the controller with it's required dependencies
$class = $injector->make($controller);
// Call the method (action) in the controller
$class->$action();
}
Finally, answer OP's question
Okay, so using this technique, let's say you have the User controller which requires the User Service (let's say UserModel) which requires Database access.
class UserController
{
protected $userModel;
public function __construct(Model\UserModel $userModel)
{
$this->userModel = $userModel;
}
}
class UserModel
{
protected $db;
public function __construct(Library\DatabaseInterface $db)
{
$this->db = $db;
}
}
If you use the code in the router, Auryn will do the following:
Create the Library\DatabaseInterface, using MySQL as the concrete class (alias'd in the boostrap)
Create the 'UserModel' with the previously created Database injected into it
Create the UserController with the previously created UserModel injected into it
That's the recursion right there, and this is the 'auto-wiring' I was talking about earlier. And this solves OPs problem, because only when the class hierarchy contains the database object as a constructor requirement is the object insantiated, not upon every request.
Also, each class has exactly the requirements they need to function in the constructor, so there are no hidden dependencies like there were with the service locator pattern.
RE: How to make it so that the connect method is called when required. This is really simple.
Make sure that in the constructor of your Database class, you don't instantiate the object, you just pass in it's settings (host, dbname, user, password).
Have a connect method which actually performs the new PDO() object, using the classes' settings.
class MySQL implements DatabaseInterface
{
private $host;
// ...
public function __construct($host, $db, $user, $pass)
{
$this->host = $host;
// etc
}
public function connect()
{
// Return new PDO object with $this->host, $this->db etc
}
}
So now, every class you pass the database to will have this object, but will not have the connection yet because connect() hasn't been called.
In the relevant model which has access to the Database class, you call $this->db->connect(); and then continue with what you want to do.
In essence, you still pass your database object to the classes that require it, using the methods I have described previously, but to decide when to perform the connection on a method-by-method basis, you just run the connect method in the required one. No you don't need a singleton. You just tell it when to connect when you want it to, and it doesn't when you don't tell it to connect.
Old Answer
I'm going to explain a little more in-depth about Dependency Injection Containers, and how they can may help your situation. Note: Understanding the principles of 'MVC' will help significantly here.
The Problem
You want to create some objects, but only certain ones need access to the database. What you're currently doing is creating the database object on each request, which is totally unnecessary, and also totally common before using things like DiC containers.
Two Example Objects
Here's an example of two objects that you may want to create. One needs database access, another doesn't need database access.
/**
* #note: This class requires database access
*/
class User
{
private $database;
// Note you require the *interface* here, so that the database type
// can be switched in the container and this will still work :)
public function __construct(DatabaseInterface $database)
{
$this->database = $database;
}
}
/**
* #note This class doesn't require database access
*/
class Logger
{
// It doesn't matter what this one does, it just doesn't need DB access
public function __construct() { }
}
So, what's the best way to create these objects and handle their relevant dependencies, and also pass in a database object only to the relevant class? Well, lucky for us, these two work together in harmony when using a Dependency Injection Container.
Enter Pimple
Pimple is a really cool dependency injection container (by the makers of the Symfony2 framework) that utilises PHP 5.3+'s closures.
The way that pimple does it is really cool - the object you want isn't instantiated until you ask for it directly. So you can set up a load of new objects, but until you ask for them, they aren't created!
Here's a really simple pimple example, that you create in your boostrap:
// Create the container
$container = new Pimple();
// Create the database - note this isn't *actually* created until you call for it
$container['datastore'] = function() {
return new Database('host','db','user','pass');
};
Then, you add your User object and your Logger object here.
// Create user object with database requirement
// See how we're passing on the container, so we can use $container['datastore']?
$container['User'] = function($container) {
return new User($container['datastore']);
};
// And your logger that doesn't need anything
$container['Logger'] = function() {
return new Logger();
};
Awesome! So.. how do I actually use the $container object?
Good question! So you've already created the $container object in your bootstrap and set up the objects and their required dependencies. In your routing mechanism, you pass the container to your controller.
Note: example rudimentary code
router->route('controller', 'method', $container);
In your controller, you access the $container parameter passed in, and when you ask for the user object from it, you get back a new User object (factory-style), with the database object already injected!
class HomeController extends Controller
{
/**
* I'm guessing 'index' is your default action called
*
* #route /home/index
* #note Dependant on .htaccess / routing mechanism
*/
public function index($container)
{
// So, I want a new User object with database access
$user = $container['User'];
// Say whaaat?! That's it? .. Yep. That's it.
}
}
What you've solved
So, you've now killed multiple birds (not just two) with one stone.
Creating a DB object on each request - Not any more! It's only created when you ask for it because of the closures Pimple uses
Removing 'new' keywords from your controller - Yep, that's right. You've handed this responsibility over to the container.
Note: Before I continue, I want to point out how significant bullet point two is. Without this container, let's say you created 50 user objects throughout your application. Then one day, you want to add a new parameter. OMG - you now need to go through your whole application and add this parameter to every new User(). However, with the DiC - if you're using $container['user'] everywhere, you just add this third param to the container once, and that's it. Yes, that totally is awesome.
The ability to switch out databases - You heard me, the whole point of this is that if you wanted to change from MySQL to PostgreSQL - you change the code in your container to return a new different type of database you've coded, and as long as it all returns the same sort of stuff, that's it! The ability to swap out concrete implementations that everyone always harps on about.
The Important Part
This is one way of using the container, and it's just a start. There are many ways to make this better - for example, instead of handing the container over to every method, you could use reflection / some sort of mapping to decide what parts of the container are required. Automate this and you're golden.
I hope you found this useful. The way I've done it here has at least cut significant amounts of development time for me, and it's good fun to boot!
This is approximately what I use.
class Database {
protected static $connection;
// this could be public if you wanted to be able to get at the core database
// set the class variable if it hasn't been done and return it
protected function getConnection(){
if (!isset(self::$connection)){
self::$connection = new mysqli($args);
}
return self::$connection;
}
// proxy property get to contained object
public function __get($property){
return $this->getConnection()->__get($property);
}
// proxy property set to contained object
public function __set($property, $value){
$this->getConnection()->__set($property, $value);
}
// proxy method calls to the contained object
public function __call($method, $args){
return call_user_func_array(array($this->getConnection(), $method), $args);
}
// proxy static method calls to the contained object
public function __callStatic($method, $args){
$connClass = get_class($this->getConnection());
return call_user_func_array(array($connClass, $method), $args);
}
}
Note it only works if there is a single database in play. If you wanted multiple different databases it would be possible to extend this but beware of late static binding in the getConnection method.
Here is an example of a simple approach:
class Database {
public $connection = null ;
public function __construct($autosetup = false){
if ($autosetup){
$this->setConnection() ;
}
}
public function getProducts(){//Move it to another class if you wish
$this->query($sql_to_get_products);
}
public function query($sql) {
if (!$connection || !$connection->ping()){
$this->setupConnection() ;
}
return $this->connection->query($sql);
}
public function setConnection(){
$this->connection = new MySQLi($a, $b, $c, $d) ;
}
public function connectionAvailable(){
return ($connection && $connection->ping()) ;
}
}
Look into using a dependency injection container, something like Pimple would be nice place to start. With a dependency injection container you 'teach' the container how to create the objects in your application, they're not instantiated until you ask for them. With Pimple, you can configure a resource to be shared so that it's only ever instantiated once during the request no matter how often you ask the container for it.
You can setup your classes to accept the container in their constructor or use a setter method to inject into your class.
A simplified example could look like this:
<?php
// somewhere in your application bootstrap
$container = new Pimple();
$container['db'] = $container->share(
function ($c) {
return new Database();
}
);
// somewhere else in your application
$foo = new Foo($container);
// somewhere in the Foo class definition
$bar = $this->container['db']->getBars();
Hope it helps.
You got some great answers already, with the majority concentrating on the aspect of injecting dependencies (which is a good thing), and only creating objects on demand.
The other aspect is the more important one: Do not put code that does any heavy work into your constructors. In case of a database object, this means: Do not connect to the database inside the constructor.
Why is this more important? Because not creating a database object because the using object also gets not created is no real optimization if the using object gets always created, but does not always run queries.
Creating an object in PHP is reasonable fast. The class code usually is available in the opcode cache, so it only triggers a call to the autoloader and then allocates some bytes in memory for the objects' properties. The constructor will run after that. If the only thing it does is copying the constructor parameters to local property variables, this is even optimized by PHP with "copy-on-write" references. So there is no real benefit if this object does not get created in the first place, if you cannot avoid it. If you can: even better.
I come from the world of Java. Java is resident in memory accross stateless HTML requests. PHP is not. That is a whole different story - and what I like about PHP.
I simply use:
$conn = #pg_connect(DBConnection);
the DBConnection is a definition containing the information about the host etc..
The # assures that the current connection is used or a new one is created. How can I do it more easily?
The data how to connect to the database is stable. The connection itself might be recreated during a request. Why should I program better then the people of PHP and recreate the #? They did that for the PHP community, let's use it.
By the way, never put heavy objects in a constructor and never let the constructor do some heavy job nor let it happen that an exception can be thrown during construction of an object. You might have an unfinished object resident in your memory. An init-method is to be preferred. I agree on that with Henrique Barcelos.
This is the way I am using mysqli. Database object behaves the same as mysqli object, can add my own methods or override existing ones, and the only difference is that the actual connection to database is not established when you create the object but on first call to method or property that needs the connection.
class Database {
private $arguments = array();
private $link = null;
public function __construct() {
$this->arguments = func_get_args();
}
public function __call( $method, $arguments ) {
return call_user_func_array( array( $this->link(), $method ), $arguments );
}
public function __get( $property ) {
return $this->link()->$property;
}
public function __set( $property, $value ){
$this->link()->$property = $value;
}
private function connect() {
$this->link = call_user_func_array( 'mysqli_connect', $this->arguments );
}
private function link() {
if ( $this->link === null ) $this->connect();
return $this->link;
}
}
Another way to achieve the same behavior is with use of mysqli_init() and mysqli_real_connect() methods, constructor initializes the object with mysqli_init(), and when you need a real connection the mysqli_real_connect() method is used.
class Database {
private $arguments = array();
public function __construct() {
$this->arguments = array_merge( array( 'link' => mysqli_init() ), func_get_args() );
}
public function __call( $method, $arguments ) {
return call_user_func_array( array( $this->link(), $method ), $arguments );
}
public function __get( $property ) {
return $this->link()->$property;
}
public function __set( $property, $value ) {
$this->link()->$property = $value;
}
private function connect() {
call_user_func_array( 'mysqli_real_connect', $this->arguments );
}
private function link() {
if ( !#$this->arguments['link']->thread_id ) $this->connect();
return $this->arguments['link'];
}
}
I tested memory consumption for both approaches and got quite unexpected results, the second approach uses less resources when connects to database and executes queries.
interface IDatabase {
function connect();
}
class Database implements IDatabase
{
private $db_type;
private $db_host;
private $db_name;
private $db_user;
private $db_pass;
private $connection = null;
public function __construct($db_type, $db_host, $db_name, $db_user, $db_pass)
{
$this->db_type = $db_type;
$this->db_host = $db_host;
$this->db_name = $db_name;
$this->db_user = $db_user;
$this->db_pass = $db_pass;
}
public function connect()
{
if ($this->connection === null) {
try {
$this->connection = new PDO($this->db_type.':host='.$this->db_host.';dbname='.$this->db_name, $this->db_user, $this->db_pass);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $this->connection;
} catch (PDOException $e) {
return $e;
}
} else {
return $this->connection;
}
}
}
How about this? In connect(), check if a connection has already been established, if yes, return it, if not, create it and return it. This will prevent you from having TOO many connections open. Let's say, in your controller action, you want to call two methods of UserRepository (that depends on the Database), getUsers() and getBlockedUsers(), if you call these methods, connect() will be called in each one of them, with this check in place it will return the already existing instance.
You could use an singleton pattern to achive this and request everytime you need the database a database object. This results in something like this
$db = DB::instance();
where DB::instance is declared something like this
class DB {
//...
private static $instance;
public static function instance() {
if (self::$instance == null) {
self::$instance = new self();
}
}
//...
}
<?php
mysql_select_db('foo',mysql_connect('localhost','root',''))or die(mysql_error());
session_start();
function antiinjection($data)
{
$filter_sql = stripcslashes(strip_tags(htmlspecialchars($data,ENT_QUOTES)));
return $filter_sql;
}
$username = antiinjection($_POST['username']);
$password = antiinjection($_POST['password']);
/* student */
$query = "SELECT * FROM student WHERE username='$username' AND password='$password'";
$result = mysql_query($query)or die(mysql_error());
$row = mysql_fetch_array($result);
$num_row = mysql_num_rows($result);
/* teacher */
$query_teacher = mysql_query("SELECT * FROM teacher WHERE username='$username' AND password='$password'")or die(mysql_error());
$num_row_teacher = mysql_num_rows($query_teacher);
$row_teahcer = mysql_fetch_array($query_teacher);
if( $num_row > 0 ) {
$_SESSION['id']=$row['student_id'];
echo 'true_student';
}else if ($num_row_teacher > 0){
$_SESSION['id']=$row_teahcer['teacher_id'];
echo 'true';
}else{
echo 'false';
}
?>
and in the php file insert javascript
<script>
jQuery(document).ready(function(){
jQuery("#login_form1").submit(function(e){
e.preventDefault();
var formData = jQuery(this).serialize();
$.ajax({
type: "POST",
url: "login.php",
data: formData,
success: function(html){
if(html=='true')
{
window.location = 'folder_a/index.php';
}else if (html == 'true_student'){
window.location = 'folder_b/index.php';
}else
{
{ header: 'Login Failed' };
}
}
});
return false;
});
});
</script>
another connection
<?php
class DbConnector {
var $theQuery;
var $link;
function DbConnector(){
// Get the main settings from the array we just loaded
$host = 'localhost';
$db = 'db_lms1';
$user = 'root';
$pass = '';
// Connect to the database
$this->link = mysql_connect($host, $user, $pass);
mysql_select_db($db);
register_shutdown_function(array(&$this, 'close'));
}
//*** Function: query, Purpose: Execute a database query ***
function query($query) {
$this->theQuery = $query;
return mysql_query($query, $this->link);
}
//*** Function: fetchArray, Purpose: Get array of query results ***
function fetchArray($result) {
return mysql_fetch_array($result);
}
//*** Function: close, Purpose: Close the connection ***
function close() {
mysql_close($this->link);
}
}
?>

Dependency injection and/or factory pattern

Not sure if my title is correct cause I am not even sure I am using the correct terms.
I have a class that has a property that is an object. When setting this property the object has to be created. My question is how do I do this without tight coupling?
Example:
class A
{
protected $_depending;
protected $_somePropertyObject;
public function __construct(\Lib\Dependency $depending)
{
$this->_setDepending($depending);
}
protected function _setDepending(\Lib\Dependency $depending)
{
$this->_depending = $depending;
}
public function setSomeProperty($someProperty)
{
// I want to prevent this
$this->_somePropertyObject = new \Lib\some\Object($someProperty);
}
}
I could just pass the required object through the construct but what happens more are needed?
When if I understand correctly the factory pattern, what would this change? I would still need to create the object somewhere? Not the object itself but the factory. Again tight coupling? Seems endless to me. When re factoring class(es) it however is isolated where and how the class(es) are made.
If I set the setSomeProperty function to only accept \Lib\some\Object then is still needs to be created by the parent object that is passing it to begin with. Seems only to shift the placement of where it is created?
Hopefully I am clear enough in what I am trying to ask.
Thanks in advance!
EDIT What I am asking is the sequence of what is created when,where,why.
The purpose of a factory in dependency injection patterns is to produce instances for another instance, without that other instance needing to know how to produce it.
At its core, a "factory" is just an object-returner: something that returns an instance when invoked.
This is easier to see in more capable languages. For example in Python classes are callable (there is no new operator), and invoking a class produces an instance of the class. So classes can be their own factories if the class requires no arguments. Likewise any zero-argument function that returns an instance can be considered a factory. This makes dependency injection very clear and free-of-boilerplate.
In more rigid languages (Java/C++/C# static-typed tradition, or where classes or functions are not completely first-class like in PHP), you need to obscure dependency injection behind a "pattern", because "design patterns" are missing language features. In PHP 5.3+ you can use a closure as a factory, or you can go the Java/C# way and define a FactoryInterface and a new class per factory.
For example, with your class, you could do this:
class Aprime extends A
{
public function setSomeProperty($somePropertyFactory)
{
$this->_somePropertyObject = $somePropertyFactory();
}
}
In this class, setSomeProperty requires a zero-argument callable "factory", which you could produce like this:
$other_dep_factory = function(){ return new SomeOtherClass(); };
Or like this:
class ClassFactory {
function __construct($classname, $args=array()) {
$this->class = new ReflectionClass($classname);
$this->args = $args;
}
function __invoke() {
return $this->class->newInstanceArgs($this->args);
}
}
$other_dep_factory = new ClassFactory('SomeOtherClass');
Prior to PHP 5.3, you need to do it like Java would:
interface IObjectFactory {
function getObject();
}
// this B-and-D interface is optional
// it has no body because PHP doesn't support
// type-hinting return values
interface ISomeOtherClassFactory {}
class SomeOtherClassFactory implements ISomeOtherClassFactory {
function getObject() {
return new SomeOtherClass();
}
}
class Aprime extends A
{
public function setSomeProperty(ISomeOtherClassFactory $somePropertyFactory)
{
$this->_somePropertyObject = $somePropertyFactory->getObject();
}
}
$other_dep_factory = new SomeOtherClassFactory();
$myAprimeObject->setSomeProperty($other_dep_factory);
So when do you use a factory? Whenever an object needs to create another object. If the object just needs to use another object, just pass in an instance.
I like to use the Factory Pattern when you need to collect "information" to create the object that's stored in $_somePropertyObject. For instance let's say you have to assign values to some properties to instantiate it or run a couple of methods right after you instantiate it.
Also, you'll want to consider whether you might need to later change the inheritance tree. If you might be assigning $_somePropertyObject a \Lib\some\Object now, you might find yourself wishing you could easily swap it out for a \Lib\some\FancyObject later. If you use Dependency Injection, you can easily swap subtypes.
Here's a primer: http://net.tutsplus.com/tutorials/php/the-whens-and-whys-for-php-design-patterns/
Also, too: https://stackoverflow.com/a/2083455/1121827

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);
}
}

Construction of a singleton class

An ethical question here.
I'm planning on using several manager classes in my new project that will be performing various tasks across the whole project. These classes are singletons, but require construction based on parameters.
As to when/where this construction has to happen, I have mixed feelings. I have these options so far:
Option A
It's easy to just pass these parameters to the getInstance method while having a default null value. On the very first call the parameters will be used, and any additional calls completely ignore them.
While this works, doing so feels rather unlogical, for the following reasons:
It makes documentation unclear. getInstance' first parameter must be of type Collection, but can be null... what's going on here?
You can argue that writing a line about this in the description will clear it up, but I'd prefer clarification to be unneccesary.
It feels faulty to pass getInstance any construction parameters. This is due to the fact that the method name does not explicity hint towards construction, making it unclear it will happen.
Option B
I'm thinking about a setup method. This method takes all parameters, calls the class constructor, and changes the internal class state to initialized.
When calling the getInstance method prior to setup, it will throw a NotInitializedException. After setup has been called, any additional calls to setup will result in a PreviouslyInitializedException.
After setup has been called, getInstance becomes available.
Personally, this option appeals more to me. But it feels excessive.
What option do you prefer? And why?
I would probably try and ditch the singleton approach and pass manager classes around to whatever needs them.
$manager = new Manager( $collection, $var, $var2 );
$other_class = New OtherClass( $manager );
//or
$other_class = New OtherClass;
$other_class->manager = $manager;
//or
$other_class = New OtherClass;
$other_class->setManager( $manager );
Use dependency injection to pass the Manager object around. Don't use Singleton pattern. It's a common consensus that using it creates a global state and makes your API deceptive.
PHP Global in functions (jump to answer)
Singletons are pathological liars
Inject the Manager instance to any class that needs it via the constructor. Each class should not try to instantiate Manager by themselves, the only way the classes get an instance of the Manager is by getting it from constructor.
class NeedsManager
{
protected $manager;
public function __construct(Manager $manager)
{
$this->manager = $manager;
}
}
You don't need to enforce one instance of Manager. Just don't instantiate it more than once. If all of your classes that need an instance of Manager get what they need from the constructor and never tries to instantiate it on their own, it will assure that there's just going to be one instance in your application.
How about option 3. If they are true singletons, set up properties files for their parameters for use with a no-arg getInstance.
If that doesn't fit, you might be misusing the singleton pattern.
You are looking at using a Factory design pattern. Factories are objects that act as fancy constructors for other objects. In your case, you will move setup and getInstance to the factory. The wiki article's pretty good- http://en.wikipedia.org/wiki/Factory_method_pattern
class SingletonFoo {
//properties, etc
static $singleton = NULL;
private function __constructor(){}
static function getInstance(){
if(NULL === self::$singleton) {
self::$singleton = new SingletonFoo();
}
return self::$singleton;
}
}
class FooFactory {
static $SingletonFoo = null;
static function setup($args){
if( !(NULL === self::$SingletonFoo)){
throw new AlreadyInstantiatedException();
}
self::$SingletonFoo = SingletonFoo::getInstance();
//Do stuff with $args to build SingletonFoo
return self::$SingletonFoo;
}
static function getInstance(){
if(NULL === self::$SingletonFoo) {
throw new NotInstantiatedException();
}
return self::$SingletonFoo;
}
}
Don't use Singleton, use Resources Manager (or Service Container, or DI Container):
class ResourceManager
{
protected static $resource;
public static function setResource($resource)
{
if (!empty(self::$resource)) //resource should not be overwritten
{
if ($resource!=self::$resource) return false;
else return true;
}
self::$resource = $resource;
return true;
}
public static function getResource()
{
return self::$resource;
}
}
Resource Manager allows you to set any custom classes for unit-testing (like dependency injection), you can just get needed resources without requesting them in constructor (I like DI, but sometimes it's just more handy to use empty constructors).
Ready-to-use variant: http://symfony.com/doc/current/book/service_container.html (I don't like to move logic from code to configs, but in stand-alone module it looks acceptable).

Categories