在PHP中访问单例方法

时间:2009-08-03 08:44:09

标签: php oop static singleton methods

我刚刚开始我的OOP之旅 - 我现在正在尝试推出自己的MVC - 纯粹是出于学习目的。我正在编写Apress PHP-Objects模式实践手册中的教程。我使用私有__construct / __克隆技术创建了一个注册表单例对象:

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 个答案:

答案 0 :(得分:6)

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 :(得分:1)

你需要在一个实例上调用setVal(),而不是类本身,所以你可以这样做:

Registry::getInstance()->set('page', $page);

答案 2 :(得分:0)

另一种方法是将对象创建放在类中,而不是在每次使用时引用它:

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

只用Registry::set('page', $page);

来调用它

这样你就可以在使用它时得到更好的代码,即使单例仍然应该被视为警告标志(如果你搜索,已经有很多关于堆栈溢出的原因的好线程。)