【问题标题】:Accessing singleton methods in PHP在 PHP 中访问单例方法
【发布时间】:2010-11-16 07:33:44
【问题描述】:

我刚刚开始我的 OOP 之旅 - 我目前正在尝试推出自己的 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);

我得到一个解析错误。我只能使用范围解析运算符访问方法 - 即'::'。

我假设这是因为对象包装器尚未实例化 - 但我只是想与大家验证/讨论这个问题......

【问题讨论】:

    标签: php oop static singleton methods


    【解决方案1】:

    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() 方法而不跳过同一个圈 - 还是我必须为每个想要访问它的方法的对象初始化该对象?
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      这样你可以在使用它的地方获得更好的代码,即使单例仍然应该被视为一个警告信号(如果你搜索,已经有很多关于为什么在 stackoverflow 上的好线程)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多