I am using a Factory class to manage the instantiation of objects and am passing into their constructors any dependency objects (Dependency Injection) e.g.
function createBasket() {
//pass in dependent objects
$apiCon = $this->createAPIConnector($this);
$basket = new Basket($this, $apiCon);
return $basket;
}
I am trying to avoid using the 'new' keyword within any classes (other than Factory), to allow simpler and more robust unit test, clearer code etc.
Now, my question relates to configuration values that many classes require e.g.
$apiURL = 'http://some.api.com';
$apiKey = 'abcde12345';
$adminEmail = 'someone#site.com';
These values remain constant for each application instance. I currently have them in a singleton class Config and they are reachable from within any class by the following:
$cfg = Config::getInstance();
$address = $cfg->apiURL;
However, this class instance is still a dependency within any Class that calls it, so should I think about passing this into class constructors, e.g.
function createBasket() {
//pass in dependent objects
$apiCon = $this->createAPIConnector($this);
$cfg = Config::getInstance();
//pass singleton config object to constructor
$basket = new Basket($this, $apiCon, $cfg);
return $basket;
}
...or perhaps pass them in via a set method, rather than via constructor:
function createBasket() {
//pass in dependent objects
$apiCon = $this->createAPIConnector($this);
$basket = new Basket($this, $apiCon);
//pass singleton config object to setter
$basket.setConfig(Config::getInstance());
return $basket;
}
Any guidance on the best approach would be much appreciated.
Thanks, James
Seems like that defeats the purpose of having a singleton config object that's globally available. The entire point is to avoid having to pass it as a parameter to every class you make.
Ive always seen them made as constants. I don't know that this is the "best" solution but I've seen this, and used it many times. Because its a const (the same is true for static vars, I would be interested to hear why one is better than the other) you don't need to instantiate the class which would probably save you some overhead if you want to be nit picky...
class SomeClass
{
const MYCONS = "APIKEY or Whateva";
}
then in when you need to use it require the file and do something like
SomeClass::MYCONST //to get your config info
I use a similar method, setting everything up in a single array or file and defining it accordingly:
$config = array(
'MYCONST_1'=>'myValue',
'USER'=>'username',
'PASSWORD'=>'y3ahr1ght'
);
foreach($config as $const=>$value){
define($const,$value);
}
Related
I was wondering if there's a good way to implement the registry pattern in PHP, let me be more clear:
I do know that a Registry is used when you need to keep track of the object you instantiate in order to reuse them and not re-instantiate them again from script to script, e.g. I have a Database class that I want to instantiate only once and then use for all my scripts and I do not want to re-instantiate it again and again. Another example could be a User class that represents an instance of the currently logged in user. I could not use a Singleton in this case, cause e.g. I need another User instance for example when I want to retrieve a friend of the currently logged in user etc.
So I came up with the idea that the Registry better suits this kind of needs in such cases.
I also know that there are two ways of implementing it, or better two ways in order to access the stored instances:
Explicitly or externally, meaning that the Registry should be called every time you need to recover an instance inside your scripts or you need to put an instance inside of it;
Implicitly or internally, meaning that you make kind of an abstract class with a getInstance() method that returns an instance with the get_called_class() late static binding feature, adds it to the registry and then return that instance from the registry itself taking care that if a $label parameter is passed to the getInstance() method, then that particular instance from the registry will be returned. This approach is kinda transparent to the consumer and in my opinion is cleaner and neater (I'll show both implementations, though).
Let's take a basic Registry (really simple implementation, just an example took from a book):
class Registry {
static private $_store = array();
static public function set($object, $name = null)
{
// Use the class name if no name given, simulates singleton
$name = (!is_null($name)) ? $name: get_class($object);
$name = strtolower($name);
$return = null;
if (isset(self::$_store[$name])) {
// Store the old object for returning
$return = self::$_store[$name];
}
self::$_store[$name]= $object;
return $return;
}
static public function get($name)
{
if (!self::contains($name)) {
throw new Exception("Object does not exist in registry");
}
return self::$_store[$name];
}
static public function contains($name)
{
if (!isset(self::$_store[$name])) {
return false;
}
return true;
}
static public function remove($name)
{
if (self::contains($name)) {
unset(self::$_store[$name]);
}
}
}
I know, Registry could be a Singleton, so you never have two Registry at the same time (who needs them someone could think, but who knows).
Anyway the externally way of storing/accessing instances is like this:
$read = new DBReadConnection;
Registry::set($read);
$write = new DBWriteConnection;
Registry::set($write);
// To get the instances, anywhere in the code:
$read = Registry::get('DbReadConnection');
$write = Registry::get('DbWriteConnection');
And internally, inside the class (taken from the book) when getInstance is called:
abstract class DBConnection extends PDO {
static public function getInstance($name = null)
{
// Get the late-static-binding version of __CLASS__
$class = get_called_class();
// Allow passing in a name to get multiple instances
// If you do not pass a name, it functions as a singleton
$name = (!is_null($name)) ?: $class;
if (!Registry::contains($name)) {
$instance = new $class();
Registry::set($instance, $name);
}
return Registry::get($name);
}
}
class DBWriteConnection extends DBConnection {
public function __construct()
{
parent::__construct(APP_DB_WRITE_DSN, APP_DB_WRITE_USER, APP_DB_WRITE_PASSWORD);
} }
class DBReadConnection extends DBConnection {
public function __construct()
{
parent::__construct(APP_DB_READ_DSN, APP_DB_READ_USER,APP_DB_READ_PASSWORD);
}
}
Apparently referring to the registry indirectly (second case) seems more scalable for me, but what if some day I would need to change the registry and use another implementation, I would need to change that calls to Registry::get() and Registry::set() inside the getInstance() method in order to suit the changes or is there a smarter way?
Did someone of you came across this problem and found an easy way to interchange different registries depending on the type of application on the complexity etc.?
Should be a configuration class the solution? Or is there a smarter way to achieve a scalable registry pattern if it is possible?
Thanks for the attention! Hope for some help!
First of all. It's great that you spotted the problem of your approach by yourself. By using a registry you are tight coupling your classes to the registry where you pull your dependencies from. Not only that, but if your classes have to care about how they are stored in the registry and get grabbed from it (in your case every class would also implement a singleton), you also violate the Single-Responsibility-Principle.
As a rule of thumb keep in mind: Accessing objects globally from within a class from whatever storage will lead to tight coupling between the class and the storage.
Let's see what Martin Fowler has to say about this topic:
The key difference is that with a Service Locator every user of a service has a dependency to the locator. The locator can hide dependencies to other implementations, but you do need to see the locator. So the decision between locator and injector depends on whether that dependency is a problem.
and
With the service locator you have to search the source code for calls to the locator. Modern IDEs with a find references feature make this easier, but it's still not as easy as looking at the constructor or setting methods.
So you see it depends on what you are building. If you have a small app with a low amount of dependencies, to hell with it, go on with using a registry (But you absolutely should drop a classes behavior to store itself into or getting grabbed from the registry). If that's not the case and you are building complex services and want a clean and straightforward API define your dependencies explicitly by using Type Hints and Constructor Injection.
<?php
class DbConsumer {
protected $dbReadConnection;
protected $dbWriteConnection;
public function __construct(DBReadConnection $dbReadConnection, DBWriteConnection $dbWriteConnection)
{
$this->dbReadConnection = $dbReadConnection;
$this->dbWriteConnection = $dbWriteConnection;
}
}
// You can still use service location for example to grab instances
// but you will not pollute your classes itself by making use of it
// directly. Instead we'll grab instances from it and pass them into
// the consuming class
// [...]
$read = $registry->get('dbReadConnection');
$write = $registry->get('dbWriteConnection');
$dbConsumer = new DbConsumer($read, $write);
Should be a configuration class the solution? Or is there a smarter way to achieve a scalable registry pattern if it is possible?
That approach is encountered very often and you maybe have heard something about a DI-Container. Fabien Potencier writes the following:
A Dependency Injection Container is an object that knows how to instantiate and configure objects. And to be able to do its job, it needs to knows about the constructor arguments and the relationships between the objects.
The boundaries between a service locator and a DI-Container seem to be pretty blurry but I like the concept to think about it like that: A Service Locator hides the dependencies of a class while a DI-Container does not (which comes along with the benefit of easy unit testing).
So you see, there is no final answer and it depends on what you are building. I can suggest to dig more into the topic since how dependencies are managed is a core concern of every application.
Further Reading
Why Registry Pattern is antipattern. And what is alternative for it.
Service Locator is an Anti-Pattern
Do you need a Dependency Injection Container?
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Dependecy Hell - how does one pass dependencies to deeply nested objects
Lately I've been struggling with this particular problem. For testing and managing reasons I decided it would be a better option to inject an object like $config to those who need it. While at start it was ok, later it started polluting the code.
For example:
Object A uses object B to do its job, object B uses strategy object C, object C uses object D, which needs $config object. So, I have to keep passing $config down this whole chain
In my code I have two objects like that to pass through, which makes constructors big, having duplicated code and generally it smells wrong.
I would appreciate any help in refactoring this relationship.
Instead of (pseudo code as general advice) ...
config <-- ...
A.constructor (config) {
this.foo = config.foo
this.bar = config.bar
this.objectB = createB (config)
}
B.constructor (config) {
this.frob = config.frob
this.objectC = createC (config)
}
C.constructor (config) {
this.frobnicate = config.frobnicate
this.objectD = createC (configD)
}
you should only pass what is really needed:
config <-- ...
A.constructor (foo, bar, frob, frobnicate) {
this.foo = foo
this.bar = bar
this.objectB = createB (frob, frobnicate)
}
B.constructor (frob, frobnicate) {
this.frob = frob
this.objectC = createC (frobnicate)
}
C.constructor (frobnicate) {
this.frobnicate = frobnicate
}
Have your state as local as possible. Global state is the root of an indefinite amount of debugging horror scenarios (as I smell you've just faced).
Alternatively, many classes don't have to know how their objects look like, they are just interested in the public interface. You can apply dependency inversion, then:
config <-- ...
objectC = createC (config.frobnicate)
objectB = createB (config.frob, objectC)
objectA = createA (config.foo, config.bar, objectB)
Using dependency inversion means freeing your classes from needing to know too much. E.g., a Car does not need to know about Trailer and its composition, it just needs to know about CouplingDevice:
trailer = createTrailer (...)
couplingDevice = createCouplingDevice (...)
car.install (couplingDevice)
couplingDevice.attach (trailer)
It looks like you need to use a singleton or a registry patterns.
The singleton consist of a class (with private constructor) that can be created by a static method in order to obtain the same object (forgive me for the simplification) every time you need it.
It follow this scheme:
class Config {
static private instance=null;
private function __constructor() {
// do your initializzation here
}
static public function getInstance() {
if (self::instance==null) {
self::instance== new Config();
}
return self::instance;
}
// other methods and properties as needed
}
In this way you can obtain the desired object where you need it with something like
$config = Config::getInstance();
without passing it down in your call stack without resorting to globals variables.
The registry has a similar working scheme but let you create a sort of registry, hence the name, of objects you need to make available.
Am I right in thinking that $config contains... well, configuration information that is required by a large portion of your application? If so, it sounds like you should consider the (ubiquitious) singleton design pattern.
If you're not already familiar with it, it is a technique which allows only one instance of a class throughout the run-time of your application. This is very useful when maintaining application-wide values, since you do not run the risk of instantiating a second object; nor are you passing around 'copies' of objects.
As an example, examine the following:
<?php
class Test {
private static $instance;
private function __construct() { } // Private constructor
static function instance() {
if (!isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
}
$a = Test::instance();
$b = Test::instance();
$a->property = 'abc';
var_dump($a->property);
var_dump($b->property);
?>
You will see that both 'instances' contain the 'property' with value 'abc' since they are both actually the same instance. I apologize if you are already familiar with this technique, but it certainly sounds like the thing you are looking for!
Edit
As pointed out below, this can still be cloned. If you really wanted to prevent this happening, you would have to override the magic method __clone() to stop this happening. The serialization observation is just being pedantic, though.
Main goal is to make core classes (instantiated with params) available from any place in application - in controllers, mappers, models, helpers etc.
For example, we have mapper which depends on Database object:
class Foo_Mapper
{
private $database;
public function __construct(Database $database)
{
$this->database = $database;
}
public function getFoo(array $criteria)
{
// ...
}
}
Variant 1: Basic dependency injection. The problem is that every time when I need to create mapper, I also need to instantiate a database object (with params).
$database = new Database($params);
$foo_mapper = new Foo_Mapper($database);
Variant 2: Registry. Core objects are instantiated and put into registry so every other object can easily access them.
// Somewhere in bootstrap...
$registry = Registry::getInstance();
$registry->database = new Database($params));
// Usage
$registry = Registry::getInstance();
$foo_mapper = new Foo_Mapper($registry->database);
Is there a better way to do what I want? Any drawbacks?
Variant 1: Basic dependency injection. The problem is that every time when I need to
create mapper, I also need to instantiate a database object (with params).
or passing it along. If you use a Dependency Injection Container, you would even have to do that manually: you simply add that you need to retrieve a Database, and a Database will be created (or reused) for you. Ask the Container to create a controller, and make sure you list your dependencies in the constructor. There are a few decent Dependency Injection containers for PHP, to wit:
Bucket https://github.com/troelskn/bucket
Symfony Dependency Injection http://components.symfony-project.org/dependency-injection/
Phemto http://phemto.sourceforge.net/
Sphoof\Container http://code.google.com/p/sphoof/source/browse/lib/container.php?repo=v2
For full disclosure: I wrote the last one.
Variant 2: Registry. Core objects are instantiated and put into registry so every other
object can easily access them.
You could make the registry non-static, but if you're going to rely on a Registry object in your application, you might as well leave it static. This is a perfectly viable solution, with one obvious drawback: you don't know what objects are used by what objects by looking at the API. You'll have to dig into the code.
You could make this a Singleton. Like this:
class Database
{
private static $instance = null;
public static getInstance()
{
if (self::$instance == null) self::$instance = new Database();
return self::$instance;
}
// ... METHODS ... //
// ... METHODS ... //
// ..... //
}
Then you can use
new Foo_Mapper(Database::getInstance());
It looks like you did this with your registry. Then you don't really need your registry anymore. Though if your classes are coded by someone else you would still have to use something like a registry or make a helper class/function for every of those classes that do not use the singleton pattern.
I think the way you illustrated it seems ok to me. It would be bad if you call your registry from within Foo_Mapper, because that class should probably not know about the existence of the registry, but this way looks ok.
What is the best way to share objects between other classes?
For example; a "database" object with functions that are required by the "article" and "user" objects.
I don't want to use globals (that includes singletons) or create a new instance of the object in each class, such as
function __construct() {
$this->database = new database;
$this->cache = new cache;
}
Would passing the objects in, eg.
class test{
function __construct( $obj ) {
$this->obj = $obj;
}
}
$database = new database;
$test = new test( $database );
Be the way to go?
Yes. Passing the objects to the constructor - or to a setter - is the best way to go. This pattern is known as dependency injection. It has the added benefit that it makes your code easier to test (using stubs or mocks).
Yes, that's pretty much the way you want to do. If a class has external requirements, don't create them inside the class, but require them as arguments in the constructor.
The way to go would be singletons if they have a single instance. If not, the only way is to pass them during initialization (say: in the constructor).
That would be a step in the right direction, but it does seem to me that you do actually want a singleton there, even if not actually constrained in code.
You could also use objects that have been loaded in session or in cache (APC,memcached) before.
Personnaly i think singleton is the best way to go there (especially for database class)
I'm currently creating blog system, which I hope to turn into a full CMS in the future.
There are two classes/objects that would be useful to have global access to (the mysqli database connection and a custom class which checks whether a user is logged in).
I am looking for a way to do this without using global objects, and if possible, not passing the objects to each function every time they are called.
You could make the objects Static, then you have access to them anywhere. Example:
myClass::myFunction();
That will work anywhere in the script. You might want to read up on static classes however, and possibly using a Singleton class to create a regular class inside of a static object that can be used anywhere.
Expanded
I think what you are trying to do is very similar to what I do with my DB class.
class myClass
{
static $class = false;
static function get_connection()
{
if(self::$class == false)
{
self::$class = new myClass;
}
return self::$class;
}
// Then create regular class functions.
}
What happens is after you get the connection, using $object = myClass::get_connection(), you will be able to do anything function regularly.
$object = myClass::get_connection();
$object->runClass();
Expanded
Once you do that static declarations, you just have to call get_connection and assign the return value to a variable. Then the rest of the functions can have the same behavior as a class you called with $class = new myClass (because that is what we did). All you are doing is storing the class variable inside a static class.
class myClass
{
static $class = false;
static function get_connection()
{
if(self::$class == false)
{
self::$class = new myClass;
}
return self::$class;
}
// Then create regular class functions.
public function is_logged_in()
{
// This will work
$this->test = "Hi";
echo $this->test;
}
}
$object = myClass::get_connection();
$object->is_logged_in();
You could pass the currently global objects into the constructor.
<?php
class Foo {
protected $m_db;
function __construct($a_db) {
$this->m_db = $a_db;
}
}
?>
I recently revamped my framework in preparation for the second version of our company's CMS. I undid a huge amount of the things I made static in order to replace them with normal objects. In so doing, I created a huge amount of flexibility that used to rely on me going through and hacking into core files. I now only use static constructs when the only alternative is global functions, which is only related to low-level core functionality.
I'm going to show a few lines of my bootstrap.php file (all of my requests get sent through that file, but you can achieve the same result by including it at the top of every file) to show you what I mean. This is an pretty hefty version of what you'd probably use in your situation, but hopefully the idea is helpful. (This is all slightly modified.)
//bootstrap.php
...
// CONSTRUCT APPLICATION
{
$Database = new Databases\Mysql(
Constant::get('DATABASE_HOST'),
Constant::get('DATABASE_USER'),
Constant::get('DATABASE_PASSWORD'),
Constant::get('DATABASE_SCHEMA')
);
$Registry = new Collections\Registry;
$Loader = new Loaders\Base;
$Debugger = new Debuggers\Dummy; // Debuggers\Console to log debugging info to JavaScript console
$Application = new Applications\Base($Database, $Registry, $Loader, $Debugger);
}
...
As you can see, I have all kind of options for creating my application object, which I can provided as an argument in the constructor to other objects to give them access to these "global" necessities.
The database object is self-explanatory. The registry object acts as a container for object I may want to access elsewhere in the application. The loader acts as a utility for loading other resources like template files. And the debugger is there to handle debug output.
I can, for example, change the database class that I instantiate and, voila I have a connection to a SQLite database. I can change the class of the debugger (as noted) and now all of my debug info will be logged to my JavaScript console.
Okay, now back to the issue. How do you give other objects access to all of this? You simply pass it in an argument to the constructor.
// still bootstrap.php
...
// DISPATCH APPLICATION
{
$Router = new Routers\Http($Application);
$Router->routeUri($_SERVER['REQUEST_URI']);
}
...
Not only that, but my Router (or whatever object I construct with it) is more flexible, too. Now I can just instantiate my application object differently, and my Router will behave differently accordingly.
Well, if you already have some object by which you refer to the blog system, you can compose these objects into that, so that they're $blog->db() and $blog->auth() or whatever.