I'm trying to understand what singleton is. What i have found out so far is that singleton pattern lets me create only one instance of a class.
So far no problem but when it comes to creating a singleton class in PHP i don't know how it works !
Take a look at this example:
class Foo {
static function instance() {
static $inst = null;
if ($inst === null) {
$inst = new self;
}
return $inst;
}
static function google(){
echo 'google';
}
private function __construct() { }
private function __clone() { }
private function __wakeup() { }
}
I try to make 2 instances from this class:
$obj = Foo::google();
$obj2 = Foo::google();
echo $obj2;
You can see that $obj and $obj2 are 2 different objects but steel this code works and no error is thrown ! I might be wrong or confused the purpose behind singleton. I have searched a lot about it here and there but nothing seems to answer my question.
Many thanks in advance
You aren't returning an object in your code, but your syntax suggests that you are.
$obj = Foo::instance();
Would return the one instance
$obj2 = Foo::instance();
Would then show that $obj and $obj2 are the same instance
So to give it some context, remove the word static from the google function. Then, you can do:
$obj = Foo::instance();
// $obj is now an object and can call its methods
`$obj->google();
This doesn't demonstrate the functionality of Singletons, but more the functionalty of Object Oriented Programming. But I am not convinced that you know you actually need to use a Singleton
in this exemple, you don't use the singleton, to get the instance of the singleton, you have to call foo::instance() it will always return you the same object.
Updated your code a bit, to explain you how singleton pattern works. The practical implementation of this,would be your database class, where you don't want to have multiple instance of database connection, in a single flow of execution.
class Foo {
static $inst = null;
static function instance() {
if ($inst === null) {
$inst = new self;
}
return $inst;
}
static function google(){
echo 'google';
}
private function __construct() { }
private function __clone() { }
private function __wakeup() { }
}
Now create instance of class and compare their objects using var_dump.
$obj = Foo::instance();
$obj1 = Foo::instance();
var_dump($obj === $obj1); // bool(true)
Related
I am trying to create a class which can be instantiate once.
$ins1,$ins4,$ins3
are created in such a way that if a static variable $instance is already defined it will be returned again and again.
$ins1==$ins4 returns true
instances $ins4,$ins5 are created with new keyword.When i use
$ins4==$ins5
it also returned ture.How can i be sure that only one instance is created
<?php
class Singleton{
private static $instance;
public static function getInstance(){
if(!self::$instance){
echo " I AM THE FIRST INSTANCE and i am not from bypass<br>";
self::$instance = new Singleton();
return self::$instance;
}else{
echo "i am from bypass<br>";
return self::$instance;
}
}
}
$ins1 = Singleton::getInstance();
$ins2 = Singleton::getInstance();
echo $ins1==$ins2;
echo '<br>';
$ins3 = Singleton::getInstance();
$ins4 = new Singleton();
$ins5 = new Singleton();
echo $ins4 == $ins5;
?>
You need to make the constructor protected or private, otherwise anyone can invoke it:
class Singleton {
protected __construct() {}
public static getInstance() {
...
}
}
Having said that, enforcing singletons like this is rarely a good idea. The better idea would be to simply instantiate the class only once and pass it around as needed through dependency injection; a dependency injection container which manages the instantiation and passing is helpful here.
I'm working on learning OOP PHP and have come across this:
//Store the single instance
private static $_instance;
/*
Get an instance of the database
#return database
*/
public static function getInstance () {
if (!self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
What is the point of setting $_instance to a new self()? I know that all this line is doing is creating a new instance of the class it's in but why would one need to do this? Is there any reason this would ever be needed? I don't ever even call it again in the class. Thanks for any help in advanced.
The idea is that whenever you call getInstance() throughout your code, you will always get the same instance.
This is useful in some cases where you only want to get access to the same object. Often objects like this might have a private constructor, which effectively forces you to always act on the same instance (also known as a singleton).
Generally people say 'Singletons are evil'. They are good to avoid because they can cause major design issues. In some cases they can still be a good idea though.
work example
class Singleton
{
public $data;
private static $instance = null;
public function __construct()
{
$this->data = rand();
}
public static function getInstance()
{
if (is_null(self::$instance))
self::$instance = new self;
return self::$instance;
}
//no clone
private function __clone() {}
//no serialize
private function __wakeup() {}
}
$singleton = Singleton::getInstance();
echo $singleton->data;
echo '<br>';
$singleton2 = Singleton::getInstance();
echo $singleton2->data;
echo '<br>';
This is the Singleton pattern.
It is used when you have an object that requires initialization and/or tear-down work and that work should be performed just once.
The instance cache forces there to only be one instance of the class, ever.
I'm using PDT and Aptana on Eclipse Indigo with PHP 5.3 and I want to create a singleton in a class.
By singleton, I mean I want to just have one instance of that object, and for other objects or classes to get that single instance via a function that returns that object (so this would mean I'm trying to create an object within the class that defines that object, ie: creating objA within the class objA)
I understand you can't just go a head and do this:
public $object = new Object();
with in a class definition, you have to define it in the constructor.
How can I go ahead and do this? I'm coming from Java, so it could be I'm confusing some basic stuff. Any help is greatly appreciated. Here's the code:
<?php
class Fetcher{
private static $fetcher = new Fetcher(); //this is where I get the unexpected "new" error
static function getFetcherInstance(){
return $this->$fetcher;
}
}
?>
Solved! Thanks for all the help guys!
try this:
<?php
class myclass{
private static $_instance = null;
public static function getInstance() {
if (self::$_instance === null) {
self::$_instance = new myclass();
}
return self::$_instance;
}
}
?>
and call it with:
<?php
$obj = myclass::getInstace();
?>
You cannot assign a class property in PHP like that. It must be a scalar, or array value, or the property must be set in a method call.
protected static $fetcher;
static function getFetcherInstance(){
if (!self::$fetcher) {
self::$fetcher = new Fetcher();
}
return self::$fetcher;
}
Also, notice that I did not use $this->, as that only works for object instances. To work with static values you need to use self:: when working within the class scope.
You might want to just read common design patterns on the php site. There are pretty good examples with good documentation:
http://www.php.net/manual/en/language.oop5.patterns.php
Else, a singleton is simply a method that returns one single instance of itself:
class MySingletonClass {
private static $mySingleton;
public function getInstance(){
if(MySingletonClass::$mySingleton == NULL){
MySingletonClass::$mySingleton = new MySingletonClass();
}
return MySingletonClass::$mySingleton;
}
}
Building on #periklis answer you might want separate singletons for different application scopes. For example, lets say you want a singleton of a database connection - fine. But what if you have TWO databases you need to connect too?
<?php
class Singleton
{
private static $instances = array();
public static function getInstance($name = 'default')
{
if ( ! isset(static::$instances[$name]))
{
static::$instances[$name] = new static();
}
return static::$instances[$name];
}
}
Class DB extends Singleton {}
$db_one = DB::getInstance('mysql');
$db_two = DB::getInstance('pgsql');
Alse define __clone method
class Fetcher {
protected static $instance;
private function __construct() {
/* something */
}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new Fetcher();
}
return self::$instance;
}
private function __clone() {
/* if we want real singleton :) */
trigger_error('Cannot clone', E_USER_ERROR);
}
}
Basically implementing a singleton pattern means writing a class with a private constructor and a static method to build itself. Also check PHP site for it: http://www.php.net/manual/en/language.oop5.php and http://it2.php.net/manual/en/book.spl.php
class A {
protected $check;
private function __construct($args) {
}
static public function getSingleton($args) {
static $instance=null;
if (is_null($instance)) {
$instance=new A();
}
return $instance;
}
public function whoami() {
printf("%s\n",spl_object_hash($this));
}
}
$c=A::getSingleton("testarg");
$d=A::getSingleton("testarg");
$c->whoami(); // same object hash
$d->whoami(); // same object hash
$b= new A("otherargs"); // run time error
<?php
class MyObject {
private static $singleInstance;
private function __construct() {
if(!isset(self::$singleInstance)) {
self::$singleInstance = new MyObject;
}
}
public static function getSingleInstance() {
return self::$singleInstance;
}
}
?>
class MyClass {
private static $instance;
public static function getInstance() {
if( !isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
}
Then call get instance using
MyClass::getInstance();
I have an interface in PHP
interface IDummy{
public function DoSomething();
}
I have another class that implements this interface.
class Dummy implements IDummy{
public function DoSomething(){
}
How can I type cast the Dummy Object to IDummy in PHP, so that I can call it as
$dum = new Dummy();
$instance = (IDummy)$dum;
$instance->DoSomething();
Can I do this in PHP?
Thanks and Regards
Abishek R Srikaanth
The cast is completely unnecessary. It will simply work.
And the Dummy objects will be considered an instance of IDummy if you ever check it with one of the various type hinting functions.
This works... no casting needed:
interface I {
public function foo();
};
class A implements I {
public function foo() { }
}
function test(I $obj) {
$obj->foo();
}
$a = new A();
test($a);
If class Dummy already implements interface IDummy, there's no need to cast $dum to IDummy - just call method DoSomething().
interface IDummy
{
public function doSomething();
}
class Dummy implements IDummy
{
public function doSomething()
{
echo 'exists!';
return;
}
}
$dummy = new Dummy();
$dummy->doSomething(); // exists!
The code should simply be:
$class = new ClassName;
$class->yourMethod();
As #konforce pointed out, not typecasting is required. You might want to check PHP method_exists() function http://php.net/manual/en/function.method-exists.php.
Well, it could be fun, see java functionality regarding this issue.
interface I {
public function foo();
};
class A implements I {
public function foo() { echo 'This should be accessible.'; }
public function baz() { echo 'This should not be available.'; }
}
$dum = new A();
$instance = (I) $dum;
$instance->foo(); // this should work
$instance->baz() // should not work
Note: This code throws error. It seems that you can not cast interface like that. In java is possible.
If you know the class name from the configuration or something else that you don't know, I think this should work:
$classname = 'Dummy';
$reflectionClass = new \ReflectionClass($classname);
$instance = $reflectionClass->newInstance();
// $dum = new $className; //you can do this as well I guess
if( $instance instanceof IDummy){
$instance->DoSomething();
}
What object-oriented design pattern would you use to implement a class that can only be instantiated once (in PHP)?
You really need to think about your specific situation. Here are some patterns to keep in mind when deciding what works in you need. Often, the Singleton can be used effectively with either a Service Locator or a Factory.
Singleton
Service Locator
Factories
That's a Singleton.
singleton but i always ,always think twice before making use of it.
You're looking for a Singleton.
Check out this tutorial about implementing a singleton with php (as per your tag).
Here's an Singleton pattern example in PHP. Technically, it allows up to two instances to be created, but croaks in the constructor when an instance already exists:
<?php
class Singleton {
static protected $_singleton = null;
function __construct() {
if (!is_null(self::$_singleton))
throw new Exception("Singleton can be instantiated only once!");
self::$_singleton= $this;
}
static public function get() {
if (is_null(self::$_singleton))
new Singleton();
return self::$_singleton;
}
}
$s = new Singleton();
var_dump($s);
$s2 = Singleton::get();
var_dump($s2); // $s and $s2 are the same instance.
$s3 = new Singleton(); // exception thrown
var_dump($s3);
You'll also want to take a look at __clone depending on how tightly you need to control the instance invocations.
You're looking for the Singleton pattern.
class Foo {
private static $instance = null;
private function __construct() { }
public static function instance() {
if(is_null(self::$instance))
self::$instance = new Foo;
return self::$instance;
}
public function bar() {
...
}
}
$foo = Foo::instance();
$foo->bar();
Ummmm.... singleton