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.
Related
let's say i have this class:
class DB {
private DBConnection $connection;
private string $databaseName;
public function __construct($databaseName) {
$this->databaseName = $databaseName;
}
private function initConnection(): void {
if (!isset($this->connection)) {
$this->connection = new DBConnection($this->databaseName);
}
}
public function query($str): array {
$this->initConnection();
return $this->connection->query($str);
}
public function something(): void {
$this->initConnection();
$this->connection->something();
}
}
Then I have some code that may or may not call the ->query / ->something methods, depending on the situation.
How can I avoid calling initConnection in every single place where $this->connection has to be used?
I only want to initialize it IF it is accessed, on its first access.
I already tried with the magic method __get but it only gets called if $connection is not in the class definition.
Another way is to create an accessor method (getConnection) which calls initConnection and use $this->getConnection() (returning the connection object, instead of void) instead of $this->connection, but still, initConnection would get called for nothing.
The problem with this approach is that I could accidentally still use $this->connection instead of the getter method; is there a way I can disallow the direct use of the property?
In my opinion, you are correct by concluding to use a (private) getConnection method to instantiate the connection only on its first use. And have the rest of the class method use getConnection() instead of $this->connection.
However, I also believe you are experiencing the downside of the singleton pattern. Perhaps consider refactoring out the actual DBConnection, and pass it as a constructor argument (dependency) to DB. You can then provide implementations of DBConnection that support lazy loading and singletons.
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
Sometimes when I look at code other people have written I see something like the following:
<?php
namespace sys\database;
class Statistics {
public function __construct() {
// Database statistics are gathered here using
// private methods of the class and then set to
// class properties
}
public static function getInstance() {
return new \sys\database\Statistics();
}
// ...
}
So the static function getInstance() simply returns an object of the class it belongs to. Then, somewhere else in the code I come across this:
$stats = \sys\database\Statistics::getInstance();
Which simply sets $stats to an instance of the Statistics object, ready for its class properties to be accessed to get various database statistics.
I was wondering why it was done this way as opposed to just using $stats = new \sys\database\Statistics();. At the end of the day, all the logic to gather statistics is in the constructor and the getInstance() method doesn't do anything other than returning a new object.
Is there something I'm missing here?
This is supposed to be an implementation of the Singleton pattern: http://www.oodesign.com/singleton-pattern.html
The pattern is used to never allow more than one instance of the class to be created.
However, there are a couple of flaws with the implementation you provided: the constructor should be private, and there should be a single private static instance of the class, returned every time the getInstance method is called.
This is supposed to be an implementation of the Singleton pattern, which is a term used to describe a class which can only exist once for run-time.
It seems the implementation you have is flawed however because:
there is no check to see if the class exists yet and
code can create multiple instances by calling the constructor directly (it should be made private)
That's a [bad] implementation of the Singleton pattern.
As a rule of thumb, you should avoid such pattern in favour of more convenient Dependency Injection, for instance.
I have a class userdb in which I am declaring a function that returns the connection to the database:
return $con = new PDO("mysql:host=$host;dbname=$db", $user, $pass);
I have various functions, even across other classes, where I have to access $con (e.g. to pass a query or to fetch data), but I can't access this variable.
Is there a better way to define and use a database class? Remember that I have other classes where I need to access the userdb class.
I would advise you to use the Singleton Pattern for this:
In your userdb class, declare a static property $scon:
private static $scon;
and assuming the function you mention above is named createConnection(), you should create the folowing static method:
public static function connect() {
if (empty(self::$scon)) {
$instance = new userdb();
self::$scon = $indtance->createConnection();
}
return self::$scon;
}
With this, you will be able to access your userdb connection with:
userdb::connect();
Also since this is a singleton, it will only connect once, and use that connection until the end of the script.
Note (on dependency injection): Since #KevinM1 mentioned Dependency Injection, I must add that it is also a possible, and far superior solution. It requires you to create a setConnection() method (or an Abstract ancestor) for all your classes using a database connection, and during the instatiation of these classes you may use a Factory to add the required connection to the object. This should be wrapped inside some class loader, which is avare of your model structure.
See, peace of cake, but for small and fast developement I would stick with the Singleton ;)
If it's in a class, store the instance in a property:
class userDB
{
public $dbCon = false;//because you want to access the instance
//from outside the class, I have made the property public
function connect()
{
$con = new PDO("mysql:host=$host;dbname=$db", $user, $pass);
$this->dbCon = $con;
}
}
TO access it outside of the class:
$useDBInstance->dbCon;
return $this->con
return this way from your class and call it this way..
$this->classObject->con->prepare();
Checkout my video tutorial + code for an alternative to global PHP variables.
You're doing it wrong there. You need to use a static variable if you plan to create your connection in a function and store it there. Otherwise you'll keep connecting on every function call. My tutorial explains this very concept of static variables within regular functions.
If it's not clear enough, let me know and I'll try to answer your questions.
Here's some code to accompany this:
/**
* Arguments are none or [$db, [$user, [$pass[, $host]]]].
*
* #return PDO
*/
function PdoDb(){
static $con = null; // I'm explicit :)
// Every time you pass Arguments you reconnect
if(func_num_args()){
$args = array_pad(func_get_args(), 4, null);
list($db, $user, $pass, $host) = $args;
if(empty($user)) $user = 'root';
if(empty($host)) $host = 'localhost';
$con = new PDO("mysql:host={$host};dbname={$db}", $user, $pass);
}
if(empty($con)){
trigger_error('Provide arguments to connect first.', E_USER_ERROR);
return null;
}
return $con;
}
// First run (provide arguments to connect)
PdoDb($db, $user, $pass, $host);
PdoDb($db); // Works if you connect root#localhost with no password
// From here on (it returns PDO)
PdoDb()->DoStuffOfPdo();
Once connected it stays that way. But you can reconnect at will to by providing arguments.
Well, $con will already be an object, as it's instantiating a new PDO object. Unless you're trying to add functionality to your PDO object, wrapping it is pointless.
That said, the best way to share your userdb/PDO object (depending on whether or not you stick with the wrapper) with other objects is to use Dependency Injection. That's a fancy term for passing your db to whatever object needs it. Since objects are defaultly passed by reference in PHP, if you create your db object first, all objects that receive it as a constructor/method argument will be using that same single instance.
EDIT: Link to Dependency Injection implementation
EDIT2: Clarification on DI in small projects -
The normal DI pattern generally requires a special object called a DI Container. This is a special use object that automatically injects the dependency into the object that needs it. For small projects, it's overkill. The simple, low complexity version of DI is simply:
class SomeClass {
protected $db;
public function __construct($db) {
$this->db = $db;
}
}
class SomeClass2 {
public function SomeMethod($db) {
// do something with the db
}
}
$db = new PDO(/* connection string */);
$obj = new SomeClass($db, /* other constructor args */);
// or
$obj2 = new SomeClass2(/* constructor args */);
$obj2->someMethod($db, /* method args */);
The magic is that since objects are passed by reference by default in PHP, $obj and $obj2 are using the same db connection.
The whole idea is to not blow apart scope or encapsulation by having a static method, and to ensure that classes and their methods are up front about what they require in order to work.
Singletons do the exact opposite. They're accessed through static methods, which bypass scope, and since they're invoked and not passed, they never show up in method signatures, so anyone not familiar with the code won't be aware of that hidden requirement. Even Erich Gamma, one of the people who helped codify the Singleton Pattern has regrets about it:
I'm in favor of dropping Singleton. Its use is almost always a design smell.
In PHP, where there's no concept of shared memory, and where scripts execute once per request, the only reason to want to use a singleton is to have easy access to a single resource. Since objects are passed by reference, a single instance can be shared with multiple objects naturally. From there, it's about good design and delegation.
use singlton class implimentation
class connectdb
{
protected static $_instance = NULL;
private function __construct()
{
}
public function getinstance()
{
if (null === self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
public function connect()
{
$this->connection =new PDO("mysql:host=$host;dbname=$db", $user, $pass);
}
}
for using a variable within a class function or independent function you need to place a global keyword
$conn=mysql_connect();
function test(){
global $conn;
}
now $conn will be available within the scope of test function, and it will be available everywhere when defined at the top of the script. For class also you need to do the same thing, make a object of a class and declare it as global within a function
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