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.
Related
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 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)
I'd like to have a library class that maintains state across the same request. My use case is that I want to pass 'messages' to the class, and then call them at any time from a view. Messages can be added from any part of the application.
I had originally done this via static methods, which worked fine. However, as part of the lib, I also need to call __construct and __destruct(), which can't be done on a static class.
Here's a very simple example of what I am trying to do:
class Messages
{
private static $messages = array();
public function __construct()
{
// do something
}
public function __destruct()
{
// do something else
}
public static function add($message)
{
self::$messages[] = $message;
}
public static function get()
{
return self::$messages;
}
}
I can then add messages anywhere in my code by doing
Messages::add('a new message');
I'd like to avoid using static if at all possible (testability). I have looked at DI, but it doesn't seem appropriate, unless I'm missing something.
I could create a class (non-static) instead, but how do I then ensure that all messages are written to the same object - so that I can retrieve them all later?
What's the best way to tackle this?
I looks like you could benefit from using the Singleton pattern - it is designed for an object that must have only one instance throughout a request. Basically, you create a private constructor and a static method to retrieve the sole instance. Here is an example of a singleton that will do what you describe.
<?php
class Messages
{
private static $_instance;
private $_messages = array();
private function __construct() {
// Initialize
}
static public function instance() {
if (! self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
public function add_message( $msg ) {
$this->_messages[] = $message;
}
public function get_messages() {
return $this->_messages;
}
private function __destruct() {
// Tear-down
}
}
$my_messages = Messages::instance();
$my_messages->add_message( 'How now, brown cow?' );
// ...
$your_messages = Messages::instance();
$msgs = $your_messages->get_messages();
echo $your_messages[0]; // Prints, "How now, brown cow?"
Since the constructor is private, you can only create a Messages object from within a method of the object itself. Since you have a static method, instance(), you can create a new Messages instance from there. However, if an instance already exists, you want to return that instance.
Basically, a singleton is the gatekeeper to its own instance, and it stubbornly refuses to ever let more than one instance of itself exist.
Sounds like you are wanting to do a Singleton class. This will create an instance in one class and allow you to access that same instance in another class. Check out http://www.developertutorials.com/tutorials/php/php-singleton-design-pattern-050729-1050/ for more information.
How about making it a singleton class?
class Messages
{
// singleton instance of Messages
private static $instance;
public function __construct() { ... }
public static function getInstance()
{
if (!self::$instance)
{
self::$instance = new Messages();
}
return self::$instance;
}
}
This would ensure that all your messages get written to the same object, and also allow you to call __construct and __destruct
What you need is the Singleton pattern:
final class Singleton {
// static variable to store the instance
private static $instance = NULL;
// disable normal class constructing
private function __construct() {}
// instead of using the normal way to construct the class you'll use this method
public static function getInstance() {
if (NULL === self::$instance) {
self::$instance = new self;
}
return self::$instance;
}
// disable external cloning of the object
private function __clone() {}
}
// get the instance across some of your scripts
$singleton = Singleton::getInstance();
Sounds a bit like you want a singleton, although as an anti-pattern I'd avoid it.
You could do a full static class where every static member calls a self::_isBuilt(); method to do your construct elements. Destruct is a little trickier.
The best case for your needs might be a normal (non-static) class that you build right away and then access from a global... not super neat, but allows construct/destruct and members, and your statics to use $this which could be helpful. If you don't like the global variable, you could also wrap it in a method (a trick used in JS a fair bit) but it's not really any neater.
As a normal global class:
$myClass=new myClass();
//Access anywhere as:
globals['myClass']->myFunction(..);
Wrapped in a function
function my_class() {
static $var=null;
if ($var===null) $var=new myClass();
return $var;
}
//Access anywhere as:
my_class()->myFunction(..);
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();
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