我是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 */
}
答案 0 :(得分:2)
对于常量,只允许标量值(float,int,string,bool,NULL)。但是您可以将UNKNOWN-insatnce设置为静态类变量
class User{
public static $unknown_user = NULL;
...
}
User::$unknown_user = new User("unknown");
然后是用户User::$unknown_user
,而不是UNKNOWN_USER
。
答案 1 :(得分:0)
除了标量类型之外,您不能将const
用于其他任何内容。这排除了任何物体。你想要在这里做的是制作一个物体immutable。你可以通过多种方式实现这一点,尽管它们既不简单也不简单。例如,查看Builder pattern。另一种方法是使对象可锁定。但是,实现这一目标的所有安全方法都需要您编写代码。
您可以想到的最简单的可锁定模式:
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
答案 2 :(得分:0)
你可以这样做:
<?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
被激活以禁用编辑属性。