I know singletons are bad. But is it bad for this, too?
class DaoMySQL {
private static $instance;
private $PDO;
private function __construct() {
$this->PDO = new PDO('mysql:dbname='.MYSQL_DEFAULT_DATABASE.';host='.MYSQL_HOSTNAME, MYSQL_USERNAME, MYSQL_PASSWORD);
$this->PDO->query('SET NAMES \'utf8\'');
}
/**
* #return DaoMySQL
*/
static public function singleton() {
if (!isset(self::$instance)) {
$c = __CLASS__;
self::$instance = new $c();
}
return self::$instance;
}
/**
* #return PDO
*/
public function getPDO() {
return $this->PDO;
}
}
To use this, I do something like this. (This is from my Bean class which all data objects extends.)
public function delete() {
$calledClassName = get_called_class();
$query = "DELETE FROM `" . $calledClassName::table . "` WHERE `id` = $this->id";
return DaoMySQL::singleton()->getPDO()->exec($query);
}
Many people are starting to use Dependency Injection containers to manage their objects instead of using singletons. Perhaps it's worth a look? Then all you need to ensure is that objects can access the container. You can fetch everything else from there.
Personally I use sfServiceContainer from Symfony Components. It's a stand-alone DI container and seems quite popular these days.
Update
You don't need to use a framework or a library. Fabien Potencier's articles on dependency injection should give you a good enough grasp of DI to implement your own. But why reinvent the wheel? Not using a good, existing library smells of NIH.
Note that there are many other DI libraries besides the sfServiceContainer that I use. Also note that sfServiceContainer is a completely stand-alone library. It does not need Symfony or any other framework. All it requires is plain old PHP.
The thing (well, one of them) that's wrong with Singletons is that the application should really be responsible for determining an object's life-cycle.
Have a read of Steve Yegge's article Singleton Considered Stupid
Related
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.
I've been working on a small project using PHP and MySQL. I've read a lot around about best practices on managing a connection and so on.
I've also implemented (following some posts found around) a singleton class to manage MySQL connections.
require_once 'config.inc.php';
class DbConn {
private static $instance;
private $dbConn;
private function __construct() {}
/**
*
* #return DbConn
*/
private static function getInstance(){
if (self::$instance == null){
$className = __CLASS__;
self::$instance = new $className;
}
return self::$instance;
}
/**
*
* #return DbConn
*/
private static function initConnection(){
$db = self::getInstance();
$connConf = getConfigData();
$db->dbConn = new mysqli($connConf['db_host'], $connConf['db_user'], $connConf['db_pwd'],$connConf['db_name']);
$db->dbConn->set_charset('utf8');
return $db;
}
/**
* #return mysqli
*/
public static function getDbConn() {
try {
$db = self::initConnection();
return $db->dbConn;
} catch (Exception $ex) {
echo "I was unable to open a connection to the database. " . $ex->getMessage();
return null;
}
}
}
But... If my website has like 10K visitors contemporaneously and I'm calling every time my singleton object, should I expect to have performance issues? I meant, shouldn't I have a kind of pool of connections instead of a singleton?
Using singletons in PHP is considered bad practice. From my experience the most problematic issue with them are unit tests. It is hard to ensure that two tests are independent when testing singletons.
I would delegate the responsibility for the constraint "only one instance should exists" to the code which creates the Db object.
Also for me it looks like there is a misunderstanding in how Singletons work in PHP in contrast to other languages: If you have 10.000 concurrent requests for example, then each request runs in a separate PHP process or thread, meaning they will all have their own instance of the "singleton", there is no sharing of this object for more than a single request (when running PHP in common web backend scenarios)
There is no "connection pooling" in PHP, but you can use mysqli persistent connections for mysql. It can be achieved by passing the p: in front of the hostname when creating mysqli. This might help here, but handle it with care (meaning read the documentation first)
However, just for theory, a singleton in PHP must be aware of the fact that someone could use clone. Meaning in your case it would be possible to do that:
$db = DB::getInstance();
$db2 = clone $db;
To avoid that you can implement the __clone() method like this:
public function __clone() {
throw new Exception("Can't clone a singleton");
}
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);
}
}
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');
Following on from my question on service locators I have decided to use constructor injection instead. Please consider the following code:
<?php
interface IAppServiceRegistry {
public function getDb();
public function getLogger();
}
interface IFooServiceRegistry extends IAppServiceRegistry {
public function getFooBarBazModel();
}
class AppServiceRegistry
implements IAppServiceRegistry, IFooServiceRegistry
{
private $logger;
private $db;
private $fooBarBazModel;
public function getDb() {
// return db (instantiate if first call)
}
public function getLogger() {
// return logger (instantiate if first call)
}
public function getFooBarBazModel() {
if (!isset($this->fooBarBazModel)) {
$this->fooBarBazModel = new FooBarBazModel( $this->getDb() );
}
return $this->fooBarBazModel;
}
}
// Example client classes:
/**
* Depends on db, logger and foomodel.
*/
class Foo {
private $db;
private $logger;
private $fooModel;
public function __construct(IFooServiceRegistry $services) {
$this->db = $services->getDb();
$this->logger = $services->getLogger();
$this->fooModel = $services->getFooModel();
}
}
/**
* Depends on only db and logger.
*/
class BarBaz {
private $db;
private $logger;
public function __construct(IAppServiceRegistry $services) {
$this->db = $services->getDb();
$this->logger = $services->getLogger();
}
}
Then I would add new service factory methods to the registry as the application evolved, creating segregated interfaces wherever logically appropriate.
Is this approach sane?
Although I don't normally read php, I think I understand most of it. Technically, it looks fine, but then you write
I would add new service factory methods to the registry as the application evolved
That tends to hurt the idea of loose coupling because instead of a general-purpose Service Locator you now have a specialized Service Locator.
Injecting such a serivce registry into each class works against the Single Responsibility Principle (SRP) because once a class has access to the registry, it is too easy to request yet another dependency than originally conceived, and you will end up with a God Object.
It would be better to inject the required dependencies directly into the classes that need them. Thus, your Foo class' constructor should take a db, a logger and a fooModel, while the BarBaz class should take only a db and a logger parameter.
The next question may then be: What if I need a lot of different dependencies to perform the work? That would require a truly ugly constructor with lots of parameters, and this goes against other well-known OO practices.
True, but if you need lots of dependencies, you are probably violating the SRP and should try to split your design into finer-grained objects :)
This implementation is almost the same as the service locator you previously showed us.
A good question to ask is whether upon looking at the class of your objects, you know everything about the objects needs to get their job done. In your case you still don't know.
If Foo needs the db, logger and model, you make this clear by asking for these in the constructor.
Here's a good read on the matter:
http://misko.hevery.com/code-reviewers-guide/flaw-digging-into-collaborators/
I've been grappling with this kind of problem lately. Service Locator vs Depedency Injection.
I agree with Mark that the way to go is to inject individual fine-grained objects into the constructor, as required. The only drawback, as Mark has highlighted, is that when you build a complex object graph, you inevitably have to start somewhere. This means that your high-level objects will have lots of services (objects) injected into them.
The easy way round this is to use something to do the hard work for you. The prime example of this is Google's Guice which seems to me a very good way of going about things. Sadly it's written for Java! There are PHP versions about; I'm not sure any of them quite measure up to Guice at this point.
I've written a post on this topic which goes into more detail; which you may find interesting. It includes a simple implementation of a dependency injection framework.
The bottom line is that if you've got a class Foo with a number of requirements, you can create your class as such:
/**
* Depends on db, logger and foomodel.
*/
class Foo
{
private $db;
private $logger;
private $fooModel;
/**
* (other documentation here)
* #inject
*/
public function __construct(IDbService $db, ILoggerService $logger, $iModelService $model)
{
// do something
}
}
When you want a new Foo object, you simply ask the dependency injection framework to create you one:
$foo = $serviceInjector->getInstance('Foo');
The dependency injector will do the hard work, making sure it injects the dependencies. This includes any dependencies of the dependencies, if that makes sense. In other words it will sort it all out recursively up the tree.
Later, when you find you need an IBarService object, you can just add it to the Construtor, without altering any other code!