Singleton pattern in php - php

class SingleTon
{
private static $instance;
private function __construct()
{
}
public function getInstance() {
if($instance === null) {
$instance = new SingleTon();
}
return $instance;
}
}
The above code depicts Singleton pattern from this article. http://www.hiteshagrawal.com/php/singleton-class-in-php-5
I did not understand one thing. I load this class in my project, but how would I ever create an object of Singleton initially. Will I call like this Singelton :: getInstance()
Can anyone show me an Singleton class where database connection is established?

An example of how you would implement a Singleton pattern for a database class can be seen below:
class Database implements Singleton {
private static $instance;
private $pdo;
private function __construct() {
$this->pdo = new PDO(
"mysql:host=localhost;dbname=database",
"user",
"password"
);
}
public static function getInstance() {
if(self::$instance === null) {
self::$instance = new Database();
}
return self::$instance->pdo;
}
}
You would make use of the class in the following manner:
$db = Database::getInstance();
// $db is now an instance of PDO
$db->prepare("SELECT ...");
// ...
$db = Database::getInstance();
// $db is the same instance as before
And for reference, the Singleton interface would look like:
interface Singleton {
public static function getInstance();
}

Yes, you have to call using
SingleTon::getInstance();
The first time it will test the private var $instance which is null and so the script will run $instance = new SingleTon();.
For a database class it's the same thing. This is an extract of a class which I use in Zend Framework:
class Application_Model_Database
{
/**
*
* #var Zend_Db_Adapter_Abstract
*/
private static $Db = NULL;
/**
*
* #return Zend_Db_Adapter_Abstract
*/
public static function getDb()
{
if (self::$Db === NULL)
self::$Db = Zend_Db_Table::getDefaultAdapter();
return self::$Db;
}
}
Note: The pattern is Singleton, not SingleTon.

A few corrections to your code. You need to ensure that the getInstance method is 'static', meaning it's a class method not an instance method. You also need to reference the attribute through the 'self' keyword.
Though it's typically not done, you should also override the "__clone()" method, which short circuits cloning of instance.
<?
class Singleton
{
private static $_instance;
private function __construct() { }
private final function __clone() { }
public static function getInstance() {
if(self::$_instance === null) {
self::$_instance = new Singleton();
}
return self::$_instance;
}
}
?>
$mySingleton = Singleton::getInstance();
One thing to not is that if you plan on doing unit testing, using the singleton pattern will cause you some difficulties. See http://sebastian-bergmann.de/archives/882-Testing-Code-That-Uses-Singletons.html

class Database{
private static $link=NULL;
private static $getInitial=NULL;
public static function getInitial() {
if (self::$getInitial == null)
self::$getInitial = new Database();
return self::$getInitial;
}
public function __construct($server = 'localhost', $username = 'root', $password ='tabsquare123', $database = 'cloud_storage') {
self::$link = mysql_connect($server, $username, $password);
mysql_select_db($database,self::$link);
mysql_query("SET CHARACTER SET utf8", self::$link);
mysql_query("SET NAMES 'utf8'", self::$link);
return self::$link;
}
function __destruct(){
mysql_close(self::$link);
}
}

Related

How to expend a super class object to a sub class in php?

i want to implement singleton in the data base super class.
but i want to invoke the methods from it on a sub class object
super class:
class Database {
private $conn;
public static $instance;
private function __construct($conn)
{
$this->conn = $conn;
}
public static function getInstance($conn)
{
if (!self::$instance) {
self::$instance = new Database($conn);
}
return self::$instance;
}
}
sub class:
class Article extends Database
{
public function __construct($conn)
{
parent::getInstance($conn);
}
}
--->
$article = new Article($conn);
but $conn property is not getting initialised.
is there any successful way of doing that without calling directly the super class constructor and keeping the superclass singleton design pattern? Thanks
In Singleton, you instantiate the class by calling its static method getInstance() and send parameters to stablish connection to the database, make the connection and assing it to non-static variable $conn:
class Database {
// Private to ensure you can get instance only by the static method
private static $instance;
// $conn is not static
private $conn;
private function __construct()
{
// Declared to avoid non-static instatiation
}
public static function getInstance($host, $user, $pass)
{
if (!self::$instance) {
self::$instance = new self();
// Connect to database
self::$instance->$con = new PDO($host, $user, $pass);
}
return self::$instance;
}
}
__construct() and getInstance() are already defined in parent class, no need to overwrite them
class Article extends Database
{
public function prepare($query)
{
return $this->conn->prepare($query);
}
}
Instantiate the model and start doing something:
$article = Article::getInstance("mysql:host=localhost;dbname=mydatabase;charset=UTF8", 'myuser', 'mypass');
$stmt = $article->prepare('SELECT * FROM sometable');

What is the design pattern used to write this PHP code?

what is the design pattern for this code ?
class Foo {
private $_connection;
private static $_instance;
private $_host = "Host";
private $_username = "Name";
private $_password = "encrypted Word";
private $_database = "Name";
public static function getInstance() {
if(self::$_instance = 'Connected') {
self::$_instance = new self();
}
return self::$_instance;
}
private function __construct() {
$this->_connection = new mysqli($this->_host, $this->_username,
$this->_password, $this->_database);
}
public function getConnection() {
return $this->_connection;
}
}
This should maybe be a singleton, but currently is has bugs and won't work as expected.
The aim of a singleton is, to only have one instance of a class and no possibility to create another one. To achieve this, one creates a static method (getInstance), which stores the instance of the class and lazy instantiates it.
Currently there is a bug
if (self::$instance = 'Contected') ...
First, this isn't a comparison and because of this, the value is always true and each time you call getInstance, you actually create a new one, instead of returning the singleton.
This should be changed to
if (!self::$instance) ...
To get the actual singleton, you simply have to call the getInstance-method.
$foo = Foo::getInstance();

static variable in singleton design pattern is always null

i had written a chat module and in this module for lowering pressure on database i used singleton design pattern for getting pdo Object.this is my driver class that uses singletone pattern:
class driver {
protected $_servername= "localhost";
protected $_username= "****";
protected $_password= "****";
protected $_dbname= "***";
private static $instance;
private $dbConn;
// The db connection is established in the private constructor.
public function __construct()
{
$this->dbConn = new PDO("mysql:host=$this->_servername;dbname=$this->_dbname", $this->_username, $this->_password);
// set the PDO error mode to exception
$this->dbConn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
public static function getInstance()
{
if(!self::$instance)
{
self::$instance = new driver();
}
return self::$instance;
}
public function getConnection()
{
return $this->dbConn;
}
public function __clone() {
throw new Exception("Can't clone a singleton");
}
}
in chat class in constructor i use this codde to get the instance:
$instance = driver::getInstance();
$conn = $instance->getConnection();
$this->_conn =$conn;
so if i put a code like
echo 123;die();
inside getinstance static method like this:
if(!self::$instance)
{
self::$instance = new driver();
echo 1111;die();
}
it always returns 1111. why static$instance variable not being filled or stay being filled with driver object?

Best way to adapt a factory method to an interface

I'm trying to create the skeleton of a basic framework, but I've stumbled on a situation in which I find myself with some piece of the engine that is missing.
I have this class to manage MySQL connections:
class Mysql implements IConnection {
protected $user;
protected $pass;
protected $dbhost;
protected $dbname;
protected $dbh;
public function __construct($user, $pass, $dbhost, $dbname)
{
$this->user = $user;
$this->pass = $pass;
$this->dbhost = $dbhost;
$this->dbname = $dbname;
}
public function connect()
{
// implementation
}
public function prepare($query)
{
// implementation
}
}
Now I want to use a factory + singleton to manage a sole instance of this class:
class Database
{
private static $db;
private function __construct() {}
public function getInstance($DBType = 'mysql')
{
if (! isset(self::$db)) {
switch ($DBType) {
case 'mysql':
self::$db = new Mysql(); // <---- PROBLEM HERE!!
// more database types should follow
}
}
return self::$db;
}
}
Note that this way I should pass the factory method the connection parameters everytime I needed the database connection instance, which definitely wouldn't be convenient.
The only thing that comes to mind is to pass the db connection, previously created, to Mysql::__construct() and store it in a property, in order to use in within Mysql::prepare(), but it would break the interface: Mysql::connect() wouldn't make any sense, and I couldn't have the db connection wrapped in this class together with the query management.
What would you suggest me to do?
EDIT:
This is my own try, although I would need to change the interface, and I'm not sure if it would be a good approach:
- Changing the interface so that IConnection::connect() accepts the connection parameters instead of the constructor
class Mysql implements IConnection {
protected $dbh; // now I only need this property
public function __construct()
{
}
public function connect($user, $pass, $dbhost, $dbname)
{
// implementation
}
public function prepare($query)
{
// implementation
}
}
And the Singleton Factory:
class Database
{
private static $db;
private function __construct() {}
public function getInstance($DBType = 'mysql')
{
if (! isset(self::$db)) {
switch ($DBType) {
case 'mysql':
self::$db = new Mysql;
break;
case 'mssql':
self::$db = new Mssql;
break;
case 'postgresql':
self::$db = new Postgresql;
break;
// etc
}
}
return self::$db;
}
}
I think this way is clean enough. Some client code:
$db = Database::getInstance(Config::get('db_driver'));
$db->connect(Config::get('db_user'),
Config::get('db_pass'),
Config::get('db_host'),
Config::get('db_name'));
Suggestions and corrections are most welcome.

Share a parameters class with other classes

I would like to share the parameters taken from a table in a db.
To take these parameters, I created a class made ​​for this.
this is my scenario to share the parameters contained in a db between the various classes. is the correct approach to do this?
class Database
{
$private mys;
public function __construct()
{
$this->mys = new mysqli(....);
}
}
class params
{
$private db;
$public var1;
$public var2;
public function __construct()
{
$this->db = new Database();
}
public function getParams()
{
$result = $this->db->mys->query ("SELECT * FROM params");
while($row = $result->fetch_assoc())
{
$this->var1 = $row['var1'];
$this->var2 = $row['var2'];
}
}
}
class foo
{
private $db;
private $ps;
public function __construct()
{
$this->db = new Database;
$this->ps = new Params;
}
public function viewParams()
{
echo $this->ps->var1;
echo $this->ps->var2;
}
}
To access the private fields from other classes declare public 'getter' methods like:
public getVal1() {
return $this->val1;
}
In my modest opinion, there are various ways to share a parameters class with other classes. And they depends on how your system currently is and how it'll grow.
From what I learnt, a correct ways to pass dependencies to your classes is to inject they to the constructor, ex instead of:
class foo
{
...
public function __construct()
{
$this->db = new Database;
I would prefer to instanciate $db first:
$db = new Database();
and then
class foo
{
...
public function __construct(Database $db)
{
$this->db = $db;
This way your classes are loosely coupled and you can afford Unit Testing easily one day, working with interfaces and not concrete implementations, etc...please take a look at http://en.wikipedia.org/wiki/Dependency_injection
As a personal suggest I'll try to design the params class as an entity, mapped as a Db table object:
//entityParams.php
class EntityParams
{
private $id; //column name
private $columnA;
private $columnB;
public function setId($id)
{
$this->id = $id;
}
public function setColumnA($columnA)
{
$this->columnA = $columnA;
}
...
}
then use a Database class as a simple connector class (just to promotes single-responsibility and separation of concerns):
//Database.php
class Database
{
private $dbh = NULL;
public function connect()
{
$this->dbh = new Mysqli(...);
}
public function getConnection()
{
if(is_null($this->dbh))
{
$this->connect();
}
return $this->dbh;
}
}
and use a DatabaseManager instead, to let it do all dirty works.Something like:
//DatabaseManager.php
class DatabaseManager
{
private $db;
private $entities = array();
private $currentEntity;
public function __construct(Database $db)
{
$this->db = $db;
}
public function fromEntity($entityName)
{
$entityClass = "Entity".ucfirst($entityName);
if(!isset($this->entities[$entityClass]))
{
$this->entities[$entityClass] = $entityName;
}
$this->currentEntity = $entityClass;
return $this;
}
public function getAll()
{
$results = $this->db->getConnection()->query("SELECT * FROM {$this->entities[$this->currentEntity]}");
$entities = array();
foreach ($results->fetch_all(MYSQLI_ASSOC) as $key => $item)
{
$e = new $this->currentEntity;
$e->setId($item['id']);
$e->setColumnA($item['columnA']);
$e->setColumnB($item['columnB']);
$entities[] = $e;
}
return $entities;
}
Finally your Foo class (and everyone else) just has a simple dependency with the DatabaseManager (which could evolve as a RespositoryManager):
//Foo.php
class Foo
{
public $dbm;
public function __construct(DatabaseManager $dbm)
{
$this->dbm = $dbm;
}
public function viewParams()
{
return $this->dbm->fromEntity("params")->getAll();
}
public function viewParam($id)
{
return $this->dbm->fromEntity("params")->find(2);
}
}
//client.php
/* Here you can instantiate the classes and pass they through constructor or investigate on how to create and use a Dependency Injection Container */
$db = new Database();
$dbm = new DatabaseManager($db);
$foo = new Foo($dbm);
var_dump($foo->viewParams());
var_dump($foo->viewParam(1));
I just wrote simple basic ideas that could be worth to play around it and improve it.

Categories