Re: Singletons

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 20 Oct 2008, at 18:07, Christoph Boget wrote:
Ok, so why isn't this working as (I, at the very least) expected?

Hmm, where to start...

 class singleTon
 {
   private static $thisObj = NULL;
   private $thisProp = NULL;

   public function __construct()

A singleton would usually have a private constructor to prevent non- singleton instances.

   {
echo 'singleTon::__construct()<br>';
     if( !is_null( singleTon::$thisObj ))
     {
echo '$thisObj already set.  returning it...<br>';
       return singleTon::$thisObj;
     }
     singleTon::$thisObj = $this;

1) You don't return it unless it already exists, not that it matters because this is the constructor and you can't return anything from that.

2) The constructor has no involvement in management of the singleton instance so this is just all wrong.

   }

   public static function singleton()
   {
echo 'singleTon::singleton()<br>';
     if( is_null( singleTon::$thisObj ))
     {
       $retval = new singleTon();
     }
     return singleTon::$thisObj;
   }

That method has the same name as the class. I'm not sure what effect this will have but it's certainly to be discouraged.

    public function setThisProp( $sVal )
   {
     $this->thisProp = $sVal;
   }

   public function getThisProp()
   {
     return $this->thisProp;
   }
 }

 $one = singleTon::singleton();
 $one->setThisProp( 'Joe' );
 echo '$one->getThisProp();: [' . $one->getThisProp() . ']<br>';
 echo '$one: [<pre>' . var_export( $one, TRUE ) . '</pre>]<br>';
 $two = new singleTon();
 echo '$two->getThisProp();: [' . $two->getThisProp() . ']<br>';
 $two->setThisProp( 'Bob' );
 echo '$two: [<pre>' . var_export( $two, TRUE ) . '</pre>]<br>';
 echo '$one->getThisProp();: [' . $one->getThisProp() . ']<br>';
 echo '$two->getThisProp();: [' . $two->getThisProp() . ']<br>';
 echo '$one->getThisProp();: [' . $one->getThisProp() . ']<br>';

I would have thought that both $one and $two would be referencing the
same object but they aren't.  Apart from making the constructor
private, is there any way I can ensure that there is ever only one
instance of an object?


Here's the simplest example I can think of (untested, typed straight into my mail client)...

class Singleton
{
  static private $_instance = null;

  public static function Instance()
  {
    if (is_null(self::$_instance))
    {
      self::$_instance = new self();
    }
    return self::$_instance;
  }

  private function __construct()
  {
    // Do normal instance initialisation here
    // Nothing singleton-related should be present
  }

  public function __destruct()
  {
    // This is just here to remind you that the
    // destructor must be public even in the case
    // of a singleton.
  }

  private $var = '';

  public function SetVar($val)
  {
    $this->var = $val;
  }

  public function GetVar()
  {
    return $this->var;
  }
}

$obj1 = Singleton::Instance();
$obj1->SetVar('arse');
$obj2 = Singleton::Instance();
echo $obj2->GetVar(); // This will echo 'arse'

Singletons are not rocket science, but as with all patterns you really need to understand the theory before trying to implement and use it.

-Stut

--
http://stut.net/

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux