2013-12-08 139 views
0

我是相當新的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 */ 
} 
+1

看看[空對象模式](http://en.wikipedia.org/wiki/Null_Object_pattern),因爲這種似乎是你想要實現的。 –

+0

是的,像@fireeyedboy指出一個空對象或只是'null'可能是一個更好的返回值。因爲:如果有真正的用戶名爲「未知」,以及如果您調用用戶「未知」的登錄方法會發生什麼? – bitWorking

+0

空對象模式確實是一個我不知道的有趣模式,因爲名稱爲「未知」的真實用戶的異議確定無誤。但是我可以處理這種設計缺陷,以獲得更好的代碼可讀性。我討厭'null'作爲返回值,並且登錄方法是靜態的,所以它不會在unknown_user上調用:) – MyPasswordIsLasercats

回答

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

+0

'static' not'stat' – bitWorking

+0

@redreggae:你說得對,我糾正了它。謝謝! –

+0

非常簡單明瞭的答案。正是我需要的。謝謝 – MyPasswordIsLasercats

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 
+0

我的意圖不是不可變性 - 對不起,這不夠清楚。 – MyPasswordIsLasercats

+0

好的,np。請記住,靜態成員通常是[壞習慣](http://stackoverflow.com/questions/7026507/why-are-static-variables-considered-evil):) –

+0

是真的,它會更好,如果它會也是不可變的。 – MyPasswordIsLasercats

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被激活禁用編輯屬性。

相關問題