Доступ к одноэлементным методам в PHP - PullRequest
3 голосов
/ 03 августа 2009

Я только начинаю свое путешествие в ООП - и в настоящее время я пытаюсь развернуть свой собственный MVC - исключительно для целей обучения. Я работаю над учебником в книге Практика шаблонов Apress PHP-Objects. Я создал одноэлементный объект реестра, используя частную технику __construct / __ clone: ​​

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;
      }
  }

Я получаю экземпляр этого объекта напрямую, т.е.:

Registry::getInstance();

Однако (следуя синтаксису в учебнике) - если я пытаюсь получить доступ к публичным методам, используя метод '->' - например:

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

Я получаю ошибку разбора. Я могу получить доступ только к методам, используя оператор разрешения области видимости - т.е. '::'.

Я предполагаю, что это потому, что объектная оболочка не была создана - но я просто хочу проверить / обсудить эту проблему с вами ...

Ответы [ 3 ]

6 голосов
/ 03 августа 2009

Registry::getInstance() возвращает (фактически единственный) экземпляр класса Registry. Он имеет то же возвращаемое значение, что и new Registry(), только во всем приложении может быть только один экземпляр. Это ваши возможности доступа к методам:

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

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

Еще один трюк:

Сопоставьте get() и set() с их магическими методами.

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

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

Так что вы можете использовать либо Registry::getInstance()->set($key, $value);, либо Registry::getInstance()->$key = $value;

1 голос
/ 03 августа 2009

Вам нужно вызывать setVal () для экземпляра, а не для самого класса, поэтому вы можете сделать это:

Registry::getInstance()->set('page', $page);
0 голосов
/ 03 сентября 2012

Другая альтернатива - поместить объект создания в класс, а не ссылаться на него при каждом использовании:

public static function get( $key ) {
    $instance = self::getInstance();
    if ( isset( $instance->values[$key] ) ) {
        return $instance->values[$key];
    }
    return null;
}

И вызывать его просто Registry::set('page', $page);

Таким образомвы получите немного более приятный код, где он используется, даже если синглтон все еще следует рассматривать как предупреждающий знак (уже есть тонна хороших сообщений о том, почему в stackoverflow при поиске).

...