我对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
被激活以禁用编辑属性。