在PHP中访问单例方法

3

我刚开始学习面向对象编程,目前正在尝试自己实现MVC框架,纯粹是为了学习目的。我正在阅读Apress PHP-Objects Patterns Practice书中的教程。我使用了私有__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个回答

7

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;

这两种方法都可以用来设置注册表中的键值对,具体使用哪种方法取决于个人偏好。

那回答了我的问题... 顺便问一下 - 如果之前的进程使用Registry::getInstance初始化了Registry类,那么后续无关的类是否可以引用Registry::set()方法而不必跳过相同的步骤 - 或者我必须为每个想要访问它的方法的对象初始化该对象? - sunwukung

1
你需要在实例上调用setVal(),而不是类本身,所以你可以这样做:
Registry::getInstance()->set('page', $page);

0
另一种选择是将对象创建放在类中,而不必在每个使用时引用它:
public static function get( $key ) {
    $instance = self::getInstance();
    if ( isset( $instance->values[$key] ) ) {
        return $instance->values[$key];
    }
    return null;
}

只需使用Registry::set('page', $page);进行调用。

这样做可以让你的代码更加优雅,尽管单例模式仍应被视为警告信号(如果你搜索stackoverflow,就会发现已经有很多关于此的好帖子了)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接