What is singleton in PHP? - php

This question may be really a silly question for many. But, i could not find the exact answer for it.
What is singleton class in PHP?
I went through many tutorials, still do not understand exact meaning of it.
What I understand is that, it cannot be instantiated more than once. The object will be shared.
What does that really mean? Suppose the singleton is implemented for database connection, does it mean, that if 'A' is access the site and logging in. Meanwhile say 'B' tries to login and B will not be able to login until A logout and releases the object?

Singleton can be used like a global variable.
It can have only one instance (object) of that class unlike normal class.
When we don't want to create a more than one instance of a class like database connection or utility library we would go for singleton pattern.
Singleton makes sure you would never have more than one instance of a class.
Make a construct method private to make a class Singleton.
If you don't want to instantiate a multiple copies of class but only one then you just put it in singleton pattern and you can just call methods of that class and that class will have only one copy of it in a memory even if you create another instance of it.
If user just wants to connect to database then no need to create a another instance again if the instance already exist, you can just consume first object and make the connection happen.
e.g.
<?php
class DBConn {
private static $obj;
private final function __construct() {
echo __CLASS__ . " initializes only once\n";
}
public static function getConn() {
if(!isset(self::$obj)) {
self::$obj = new DBConn();
}
return self::$obj;
}
}
$obj1 = DBConn::getConn();
$obj2 = DBConn::getConn();
var_dump($obj1 == $obj2);
?>
Output:
DBConn initializes only once
bool(true)
Object1 and Object2 will point to the same instance
_______________________
| |
$obj1 ---->| Instance of DBConn |<----- $obj2
|_______________________|
Hope that helps!! :)

A singleton is a particular kind of class that, as you correctly said, can be instantiated only once.
First point: it isn't a PHP related concept but an OOP concept.
What "instantiated only once means?" It simply means that if an object of that class was already instantiated, the system will return it instead of creating new one.
Why? Because, sometimes, you need a "common" instance (global one) or because instantiating a "copy" of an already existent object is useless.
Let's consider for first case a framework: on bootstrap operation you need to instantiate an object but you can (you have to) share it with other that request for a framework bootstrap.
For the second case let's consider a class that has only methods and no members (so basically no internal state). Maybe you could implement it as a static class, but if you want to follow design patterns, consider AbstractFactory) you should use objects. So, having some copy of the same object that has only methods isn't necessary and is also memory-wasting.
Those are two main reason to use singleton to me.

Yes, You are right "it cannot be instantiated more than once." and this concept is very useful when you opening a database connection.
Suppose,
If someone logins, you make new database object.
If someone updates something, you make a new database object.
If someone logouts, you make a new database object.
As you can see, every time if there is interaction with database, a new object will be created and a new connection will be opened. That's a bad thing in term of efficiency.
Here singleton class really solves the problem. It makes a database connection object and holds it, whenever required it just returns it instead of ocreate a new one.
class DB{
private static $_instance = null;
private $_pdo;
private function __construct(){
try{
$this->_pdo = new PDO('mysql:host ='yourhost'; dbname = 'your_database','username','password);
echo 'connected';
}catch(PDOException $e){
die($e->getMessage());
}
}
public static function getInstance(){
if(!isset(self::$_instance)){
self::$_instance = new DB();
}
return self::$_instance;
}
}
As you can see this class checks for existing connection ($_instance attribute), and returns it if it's not been set.

More Reference: Is there a use-case for singletons with database access in PHP?
From Design Patterns - PHP: The Right Way:
When designing web applications, it often makes sense conceptually and architecturally to allow access to one and only one instance of a particular class. The singleton pattern enables us to do this.
<?php
class Singleton
{
/**
* Returns the *Singleton* instance of this class.
*
* #staticvar Singleton $instance The *Singleton* instances of this class.
*
* #return Singleton The *Singleton* instance.
*/
public static function getInstance()
{
static $instance = null;
if (null === $instance) {
$instance = new static();
}
return $instance;
}
/**
* Protected constructor to prevent creating a new instance of the
* *Singleton* via the `new` operator from outside of this class.
*/
protected function __construct()
{
}
/**
* Private clone method to prevent cloning of the instance of the
* *Singleton* instance.
*
* #return void
*/
private function __clone()
{
}
/**
* Private unserialize method to prevent unserializing of the *Singleton*
* instance.
*
* #return void
*/
private function __wakeup()
{
}
}
class SingletonChild extends Singleton
{
}
$obj = Singleton::getInstance();
var_dump($obj === Singleton::getInstance()); // bool(true)
$anotherObj = SingletonChild::getInstance();
var_dump($anotherObj === Singleton::getInstance()); // bool(false)
var_dump($anotherObj === SingletonChild::getInstance()); // bool(true)
The code above implements the singleton pattern using a static variable and the static creation method getInstance(). Note the following:
The constructor __construct is declared as protected to prevent creating a new instance outside of the class via the new operator.
The magic method __clone is declared as private to prevent cloning of an instance of the class via the clone operator.
The magic method __wakeup is declared as private to prevent unserializing of an instance of the class via the global function unserialize().
A new instance is created via late static binding in the static creation method getInstance() with the keyword static. This allows the subclassing of the class Singleton in the example.
The singleton pattern is useful when we need to make sure we only have a single instance of a class for the entire request lifecycle in a web application. This typically occurs when we have global objects (such as a Configuration class) or a shared resource (such as an event queue).
You should be wary when using the singleton pattern, as by its very nature it introduces global state into your application, reducing testability. In most cases, dependency injection can (and should) be used in place of a singleton class. Using dependency injection means that we do not introduce unnecessary coupling into the design of our application, as the object using the shared or global resource requires no knowledge of a concretely defined class.
Singleton pattern on Wikipedia

Related

How to ensure that specific objects are instantiated by another object only?

How can I ensure that an object will be instantiated only via another particular object?
For example, say I have a Registry object to store my Mappers. When client code calls the get() method on the Registry, it lazy loads and returns the requested Mapper. That's fine, except there is nothing to stop client code from creating a duplicate instance of the Mapper using the new operator.
The only option I can think of is that my Mappers require a Registry object as a parameter. Are there other options?
What do you do? Should I even bother about preventing this kind of duplication?
Perhaps you should not try to prevent people from creating instances themselves? If you don't trust yourself or your colleagues not to instantiate objects in places where they should not instantiate them, you have a problem.
If the mappers do not need a registry to function, you should not object it via the constructor. Passing it to some static method seems rather odd, and makes your code less flexible since you're using static. And how are you going to unit test the mappers, without writing some hacks to properly instantiate them via the registry you should not have need for in these tests? Good post on that here: http://kore-nordmann.de/blog/0103_static_considered_harmful.html
You can't protect from the new operator. What you could do though is that you have a get() method in your class to make your class/object singleton (or using a Registry as you do).
class clTest {
private static $oInstance;
public static function get() {
if( !self::$oInstance ) {
self::$oInstance = new clText;
}
return self::$oInstance;
}
}
if you wish to prevent outside instantiation you only need to declare __construct as private and then use a call to a static method to get an instance of the Mapper class. You can then pass in an instance of the registry class and only return a new instance if the parameter is an instance of the registry class.
class Mapper{
private __construct(){}
public static function getInstance($registry){
if($registry instanceof Registry){
return new Mapper();
}
}
}
$registry = new Registry();
$mapper = Mapper::getInstance($registry);

Dependency Injection: pulling required components when they are actually needed

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

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

Explain this singleton factory pattern

class ConnectionFactory
{
private static $factory;
public static function getFactory()
{
if (!self::$factory)
self::$factory = new ConnectionFactory(...);
return self::$factory;
}
private $db;
public function getConnection() {
if (!$db)
$db = new PDO(...);
return $db;
}
}
function getSomething()
{
$conn = ConnectionFactory::getFactory()->getConnection();
.
.
.
}
Source
There are a couple of things that i dont get
Am i right when i say "staic property of a class can be accessed without initiating the class"
what does !db do
How is this happening ConnectionFactory::getFactory()->getConnection();
Could somebody explain getFactory method
you are right here.
! is a NOT. Which means here that if $db is false then initialise it. Since its in a static method it will stay initialised and next time the existiong $db will be returned since this second time !$db == false.
like for $db it is checking if an instance of $factory exists, if not create one and returne it, otherwise return the existing one.
4.
public static function getFactory()
{
if (!self::$factory) // is self::$factory initialised?
self::$factory = new ConnectionFactory(...); //initialise it
return self::$factory; //return self::$factory
}
Also here $factory seems to be a variable that is set somewhere eles. Presumably it could contain a couple of different class names. Does not change anything to the way the function works. Its a singleton pattern
Adding a interesting link about this pattern wikipedia
For 1. yes, a static property of a class is always accessible using ClassName::$staticvarname
For 2. there is surely a bug here. it should be if(!$this->db) and all code in getConnection should use $this->db instead of $db.
the getFactory() is here an "alias" of the more standard getInstance() of Singleton pattern.
It returns the single instance of the class if existing & create the single instance if not existing.
The getFactory()->getConnection() calls is simple:
getFactory() returns the single instance of the ConnectionFactory class.
So now that you have the Singleton instance, you can perform any call on it.
The getConnection() returns the "single" PDO instance that is handled by the singleton (stored in $db member)
Correct
! is the NOT operator. Basically if (!$db) means if $db is null then execute the if block
Get factory is a function which is returning the (single) instance of ConnectionFactory, this instance has a function getConnection()
In the singleton pattern only a single instance of class should exist, which is a private static member of the class itself. The getFactory() function is the way to get a reference to this single instance (it first initializes the instance if it is null).
Yes, static denotes that it will be the same value for every object that requests it, so no instantiation is needed
! means NOT. It is most often seen as !=, denoting NOT EQUAL. In this case, it is being checked to find if the db object has been created, so it means db is NOT NULL.
3 & 4. The method that you specified is saying to use the class (without instantiating it), and call getFactory(). Which will create the factor if it is NOT NULL, otherwise, it will return the already created factory. After that, it requests the connection using the instance of the factory that was returned. Since there is only ever one factory, then we can assume that once the connection has been instantiated (in the same way that the factory was instantiated), then that connection will be available for all uses of factory moving forward
I suggest reading the wikipedia article about Singleton patterns. Hopefully, this can be useful. Also, keep in mind, generally speaking the singleton pattern has been deemed more of an anti-pattern that should be avoided. This class seems to me that it could just as easily have been created as a static class with a static method of getConnection. With the code displayed, it seems that the creation of itself is pointless here. But, that is just in this small context.

PHP class reference

To be clear, I don't want to instantiate the same class multiple times. I only want to instantiate it once, and keep track of any changes made to that instance via some reference. Is this possible, and if so how can it be done? Thanks!
You can use the Singleton pattern for this. The PHP manual has a good example and description:
The Singleton ensures that there can be only one instance of a Class and provides a global access point to that instance.
Class:
<?php
class Example
{
private static $instance;
private function __construct() {
}
public static function singleton() {
if (!isset(self::$instance)) {
echo 'Creating new instance.';
$className = __CLASS__;
self::$instance = new $className;
}
return self::$instance;
}
public function __clone() {
trigger_error('Clone is not allowed.', E_USER_ERROR);
}
public function __wakeup() {
trigger_error('Unserializing is not allowed.', E_USER_ERROR);
}
}
Usage:
$singleton = Example::singleton();
It is worth also noting these objections to the singleton pattern from the PHP manual:
The Singleton pattern is one of the more controversial patterns. Critics argue that
Singletons introduce Global State into an application and tightly
couple the Singleton and its consuming classes. This leads to hidden
dependencies and unexpected side-effects, which in turn leads to code
that is harder to test and maintain.
Critics further argue that it is pointless to use a Singleton in a
Shared Nothing Architecture like PHP where objects are unique within
the Request only anyways. It is easier and cleaner to create
collaborator object graphs by using Builders and Factory patterns once
at the beginning of the Request.
Singletons also violate several of the "SOLID" OOP design principles
and the Law of Demeter. Singletons cannot be serialized. They cannot
be subtyped (before PHP 5.3) and won't be Garbage Collected because of
the instance being stored as a static attribute of the Singleton.
See as well: Who needs singletons?
You can create Singleton pattern
class Something {
private static $instance;
private function __construct() {
}
public static function getInstance() {
if(Something::$instance == null) {
Something::$instance = new Something();
}
return Something::$instance;
}
public function someMethod() {
return "abc";
}
}
When you want to use it you call Something::getInstance()->someMethod()
Read more about singleton pattern.
To be clear, I don't want to instantiate the same class multiple times. I only want to instantiate it once, and keep track of any changes made to that instance via some reference. Is this possible, and if so how can it be done? Thanks!
Sure this is possible. You can do this literally:
First of all, as you don't want to instantiate the class multiple times, just instantiate it once:
$instance = new Class();
Then you want to keep track of changes made to that instance. I don't specifically know what you mean. Probably you mean to only keep that one instance. You just can do so, as you have only instantiated once, you can refer to that instance with the $instance variable.
Additionally you can "reference" that $instance as well in some other variable:
$reference = $instance;
You can now access the single instance of Class with the $instance and the $reference variable.
If you need to monitor the instance, I suggest you create a Decorator that does the job:
$decorator = new ClassDecorator(new Class());
The decorator can then work as an interceptor before anything reaches Class.
To find out if the inner state of a class has changed or not, you can make use of the serialize and unserialize functions as well:
$instance = new Class();
$snapshot = serialize($instance);
...
# more code, $instance is changed or not, we don't know
...
$changed = $snapshot != serialize($instance);
Hope this is helpful.
What you are trying to do is called the Singleton Pattern .. See http://en.wikipedia.org/wiki/Singleton_pattern

Categories