views:

217

answers:

2

Hi, I'm just starting my journey into OOP - and I'm currently trying to roll my own MVC - purely for learning purposes. I'm working through a tutorial in the Apress PHP-Objects Patterns Practice book. I've created a registry singleton object using the private __construct/__clone technique:

class Registry
{
  private static $instance;
  private $values = array();


  private function __construct(){}
  private function __clone(){}

  public static function getInstance(){
       if( !isset( self::$instance ) ){
         self::$instance = new Registry();
         }
       return self::$instance;
       }

  public function get( $key ) {
      if ( isset( $this->values[$key] ) ) {
          return $this->values[$key];
          }
      return null;
      }

  public function set( $key, $val ) {
      $this->values[$key] = $val;
      }
  }

I get an instance of this object directly i.e:

Registry::getInstance();

However, (following the syntax in the tutorial) - if I try and access the public methods using the '->' method - e.g:

Registry->setVal('page',$page);

I get a parse error. I can only access the methods using the scope resolution operator - i.e '::'.

I'm assuming this is because the object wrapper has not been instantiated - but I just want to verify/discuss this issue with y'all...

+1  A: 

You need to call setVal() on an instance, not the class itself, so you could do this:

Registry::getInstance()->set('page', $page);
Tom Haigh
+3  A: 

Registry::getInstance() returns a (in fact the only) instance of the class Registry. It has the same return value as new Registry(), just that there will can only one instance in your whole application. These are your possibilities to access the methods:

// #1
$registry = Registry::getInstance();
$registry->set($key, $value);

// #2
Registry::getInstance()->set($key, $value);

Another trick:

Map get() and set() to their magic methods.

public function __set($key, $value)
{
    return $this->set($key, $value);
}

public function __get($key)
{
    return $this->get($key);
}

So you can use either Registry::getInstance()->set($key, $value); or Registry::getInstance()->$key = $value;

Philippe Gerber
That answers my question....While I'm here - if an earlier process initialises the Registry class using Registry::getInstance - can subsequent unrelated classes reference the Registry::set() methods without jumping through the same hoop - or do I have to initialise that object for every object that wants to access it's methods?
sunwukung