2013-02-18 62 views
0

我如何知道在構造函數中加載什麼以及稍後使用set方法設置的內容?我如何處理多個構造參數或類變量?

例如,我有一個問題類的大部分時間將調用下面的增值經銷商:

protected $question; 
protected $content; 
protected $creator; 
protected $date_added; 
protected $id; 
protected $category; 

在我這所以只有最基本$id$question,並$content中設置的時刻構造函數,所以我不開始建立一個龐大的構造函數參數列表。然而,這意味着當我在其他地方創建一個新的問題對象時,我必須在將'setter代碼'重複遍佈整個地方之後,直接設置該對象的其他屬性。

我是否應該立即將它們全部傳入構造函數,按照我已經做到的方式進行,還是有更好的解決方案,我錯過了?謝謝。

回答

0

根據您的語言,您可以爲任何一個類使用多個構造函數。

+2

語言是PHP的注意 – john 2013-02-18 13:28:54

+0

啊OK,把我的頭,我不認爲超載的頂部(多個構造)是可能的在PHP中。但是,您可以使用可變參數來產生類似的效果。 HTTP:// PHP。net/manual/en/function.func-get-arg.php – cosmicsafari 2013-02-18 13:32:31

0

您可以使用數組作爲構造函數或setter方法的參數。

剛例如:

public function __construct($attributes = array()) { 
    $this->setAttributes($attributes); 
} 

public function setAttributes($attributes = array()) { 
    foreach ($attributes as $key => $value) { 
    $this->{$key} = $value; 
    } 
} 
+0

如果你這樣做,沒有理由甚至創建一個類。你可以簡單地將所有內容存儲在StdClass或assoc數組中。 – akimsko 2013-02-18 14:28:46

0

PHP不支持傳統的構造函數重載(其它面嚮對象語言一樣)。一種選擇是一個數組參數傳遞到構造函數:

public function __construct($params) 
{ 

} 

// calling it 
$arr = array(
    'question' => 'some question', 
    'content' => ' some content' 
    ... 
); 
$q = new Question($arr); 

利用這一點,你可以自由地通過一個可變數量的參數和有參數的順序沒有依賴性。同樣在構造函數中,您可以設置默認值,以便在變量不存在的情況下使用默認值。

+0

非常好的乾淨的解決方案。 – cosmicsafari 2013-02-18 13:34:51

+0

如果你這樣做,沒有理由甚至創建一個類。你可以簡單地將所有內容存儲在StdClass或assoc數組中。 – akimsko 2013-02-18 14:30:19

+0

@akimsko我的觀點是在構造函數中設置屬性,而不是完全刪除屬性。這是一種以乾淨的方式設置屬性的工具。它不應該消除這些屬性。 – MrCode 2013-02-18 14:31:28

0

流暢的界面是另一種解決方案。

class Foo { 
    protected $question; 
    protected $content; 
    protected $creator; 
    ... 

    public function setQuestion($value) { 
    $this->question = $value; 
    return $this; 
    } 

    public function setContent($value) { 
    $this->content = $value; 
    return $this; 
    } 

    public function setCreator($value) { 
    $this->creator = $value; 
    return $this; 
    } 

    ... 
} 

$bar = new Foo(); 
$bar 
    ->setQuestion('something') 
    ->setContent('something else') 
    ->setCreator('someone'); 

或者使用繼承...

class Foo { 
    protected $stuff; 

    public function __construct($stuff) { 
    $this->stuff = $stuff; 
    } 

    ... 
} 

class bar extends Foo { 
    protected $moreStuff; 

    public function __construct($stuff, $moreStuff) { 
    parent::__construct($stuff); 
    $this->moreStuff = $moreStuff; 
    } 

    ... 
} 

或者使用可選參數......

class Foo { 
    protected $stuff; 
    protected $moreStuff; 

    public function __construct($stuff, $moreStuff = null) { 
    $this->stuff = $stuff; 
    $this->moreStuff = $moreStuff; 
    } 

    ... 
} 

在任何情況下,有很多很好的解決方案。請不要使用單個數組作爲params或func_get_args或__ __ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _調用魔術,除非您有充分的理由這麼做,並且已經用盡了所有其他選項。

+0

單個數組似乎會在同一行的某處導致相同類型的亂碼,但redreggae的答案呢?這對我來說似乎是一個上帝的解決方案,有什麼理由不使用它?這是'_get/_set/__ call magic'的意思嗎? – john 2013-02-18 15:26:20

+0

redreggae的是好的。至少它會促使你用setter建立一個適當的課程,並且只允許你設置你在課堂上實際擁有的屬性(或者至少有setters)。然而,它確實涉及索姆(IMO不必要的)反思和檢查,以找到制定者。 __get,__set,__call部分與任何有關的答案都沒有關係。如果你不知道它們是什麼,那麼你最好不知道;)但是現在你無疑會去查看它們,這裏有一個鏈接:http://php.net/manual/en/language.oop5。 magic.php – akimsko 2013-02-18 15:37:29

0

我會傳遞一個數組給我想要設置的值的構造函數。

public function __construct(array $values = null) 
{ 
    if (is_array($values)) { 
     $this->setValues($values); 
    } 
} 

然後,你需要一種方法來setValues動態地設置的值。

public function setValues(array $values) 
{ 
    $methods = get_class_methods($this); 
    foreach ($values as $key => $value) { 
     $method = 'set' . ucfirst($key); 
     if (in_array($method, $methods)) { 
      $this->$method($value); 
     } 
    } 
    return $this; 
} 

對於這個工作,你需要setter方法爲您的屬性,如setQuestion($value)

相關問題