2010-09-24 59 views
2

嘿SO社區, 我在這裏看到:http://www.mustap.com/phpzone_post_203_setter-and-getter使用 一個類型的財產處理常見的C#的說法,那就是: 如果在C#中,你可以這樣定義一個類:我應該在PHP中使用類似C#的屬性處理嗎?

public class Person 
{ 
    private string _name; 
    public string Name 
    { 
     get{ return _name; } 
     set{ _name = value; } 
    } 
} 

然後爲什麼是明智與否在PHP中定義一個類似的特性是這樣的:

public class Person 
{ 
    private var $name;  

    public function Name() 
    { 
     if(func_num_args() == 0) { return $this->name; } 
     else {$this->name = func_get_arg(0); } 
    } 
} 
+2

一個問題:爲什麼?通過getter/setter語法('getName()'和'setName($ name)'),或者通過魔術方法(可以讓'$ foo-> name ='bar'; echo $ foo->名;')? – ircmaxell 2010-09-24 15:31:35

回答

5

IMO,在PHP中看起來並不乾淨。這就像你試圖將C#的方式嵌入到PHP中一樣,因爲你認爲這是C#的一個很好的特性。

我把它看作:在PHP中,你正在做一個單一的函數做兩個完全不同的事情,這是沒有意義的。同時,在C#中,它是單一的屬性,它被設計成對要設置/檢索的對象的單個訪問點。

+0

我的想法確切。在嘗試將功能從一種語言移植到另一種語言之前,先考慮一下並努力吧PHP通過其魔術方法處理getter/setter的苦差事。你可能想要看看那些。 – 2010-09-24 15:41:06

+2

是的,它違反了[單一責任主體](http://en.wikipedia.org/wiki/Separation_of_concerns)(對於例程而不是類)。 – ircmaxell 2010-09-24 15:41:07

+0

我相信在我的文章中說,只要你做得好,這個方法就可以實現。 – RobertPitt 2010-09-24 15:55:21

2

如果您需要做的設置,你可能想要麼定義getFoosetFoo方法,甚至BETT價值的一些額外的檢查呃使用property overloading。後者會給用戶本土財產獲取/設置的感覺。 (後者是你在C#中所做的,只是每個類只有一個方法,並不是很多。)

+0

+1迄今只有正確的答案。 – siride 2010-09-24 15:51:18

+0

+1,我還提到重載只模仿屬性,但不能取代它們。沒有真正的支持php(還)的屬性。 – user187291 2010-09-24 16:02:13

3

您違反了Single Responsibility Principle,其中一個函數既是getter又是setter。

在c#中它只是語法糖,並轉換爲getter和setter,就像你應該用php寫的一樣。

事實上,在C#中,可以進一步通過寫

public string Name { get; set; } 

簡化IT和編譯器將生成一個私人支持字段,併爲您的getter和setter函數。

+0

jQuery(一款優秀的軟件)可以一直這樣做。 'x.html(foo)'設置值,'x.html()'返回。 – user187291 2010-09-24 16:00:43

+0

這是一個偉大的軟件,但他們做出了有意識的決定,打破SRP,只有嚴格遵守標準,才能做到這一點。所有/大多數setter(用一個輸入調用的方法)返回一個jQuery對象,它允許一個可鏈接的接口。吸氣劑無參數...有時。像.attr('name')'是一個getter,'.attr('name',value)'是一個setter。這是開始變得混亂的地方。因爲它們的功能根據參數做了不止一件事情,圖書館的消費者需要了解它。這可能會讓人困惑。 – CaffGeek 2010-09-24 21:06:44

2

它是明智的,例如:

class Settings 
{ 
    private $data = array(); 

    public function __call($key,$arguments = array()) 
    { 
     return !count($arguments)) ? $this->data[$key] : $this->data[$key] = $arguments[0]; 
    } 
} 

然後做

$Settings = new Settings(); 
$Settings->name('hello'); 
$Settings->foo('bar'); 

現在,這已經創造了一個無限量準備使用匿名的功能,這樣通常可以使用2構造方法__get__set通過這種方式,您可以爲方法和變量定義分隔,示例如下

class Settings 
{ 
    private $data = array(); 

    public function __set($key,$val) 
    { 
     $this->data[$key] = $val; 
    } 
    public function __get($key) 
    { 
     return $this->data[$key]; 
    } 
} 

這則允許你設置變量,像這樣:

$Settings->foo = 'bar'; 

但你可以去遠一點那麼,創建一個變量登記制度:

所以基本上你可以改變上述類從SettingsVariableStorage並執行以下操作:

class User extends VariableStorage{} 
class Profile extends VariableStorage{} 

並使用像這樣:

$Profile = new Profile('Robert','Pitt',USER_PRIV_ADMIN); 
$Profile->id = 56; 
$Profile->userdata = $Database->GetUserData($Profile); //Reads $Profile->id 

因此,您只需定義一次方法,只要您將繼承結構構建爲良好的設計,就可以非常好地工作。

相關問題