创建类的静态实例


creating static instance of a class

我对PHP相当陌生,但事实证明我无法找到以下问题的解决方案:

我有一个简单的类:

class User{
  private $name;
  function __construct($name){
    $this->name = $name;
  }
}

我想做的就是定义它的一个静态实例,比如其中一个:

public const UNKNOWN_USER = new User("unknown);

这样我就可以在任何地方使用它作为假人,例如:

public static login($name){
  if( /* userdoesnotexist */ ){
    return UNKNOWN_USER;
  }
}

并检查它-当然:

if( login($name) == UNKNOWN_USER){
  /* I don't know you! */
}

我试过以下几种:

$UNKNOWN_USER = new User("unknown");
/* $UNKNOWN_USER not available in class-methods */
define(UNKNOWN_USER, new User("unknown"));
/* not allowed */
class User{
  const UNKNOWN_USER = new User("unknown");
  /* "new" leads to a syntax error */
}

对于常量,只允许使用标量值(float、int、string、bool、NULL)。但是,您可以将您的UNKNOWN贪得无厌设置为静态类变量

class User{
  public static $unknown_user = NULL;
  ...
}
User::$unknown_user = new User("unknown");

然后是用户CCD_ 1而不是CCD_。

除了标量类型之外,您不能将const用于其他任何类型。这排除了任何对象。您在这里想要实现的是使对象不可变。你可以用很多方法做到这一点,尽管它们既不简单也不直接。例如,看看Builder模式。另一种方法是使对象可锁定。但是,实现这一点的所有安全方法都需要您进行一些编码。

对于您的示例,我能想到的最简单的可锁定模式:

class User{
    private $name;
    private $is_locked = false;
    function __construct($name){
        $this->setName($name);
    }
    public function lock() {
        $this->is_locked = true;
    }
    public function getName() {
        return $this->name;
    }
    public function setName($name) {
        if ( $this->is_locked ) {
            throw new Exception("The object is locked");
        }
        $this->name = $name;
    }
}

现在你可以做:

$user1 = new User("John");
$user1->setName("Johnny");

但锁定对象后,就不能再操作它了:

$user1->lock();
$user1->setName("Big John"); // Exception thrown

您可以这样做:

<?php 
//Normal UnknownUser singleton pattern
class UnknownUser {
    private static $instance;
    //define properties
    public $myproperty = "hiho123";        
    private function __construct() {
    }
    public static function getInstance() {
       if(empty($instance)) {
          self::instance = new UnknownUser();
       }
       return self::instance;
    }
    //Make the class constant
    function __set($name, $value) {
        throw new Exception("Can't set property: " . __CLASS__ . "->$name");
    }
}

您可以调用UnknownUser,如下所示:

$unknownUser = UnknownUser::getInstance();

这使得这个类是全局的和常量的,不能修改,因为魔术方法__set被激活以禁用编辑属性。