2015-04-16 110 views
11

我來自C#,我很努力地找出使我的代碼可擴展的PHP方法。在PHP中使用接口

比方說,比如我有一個計算食物的攝入我的每日推薦量的功能。它看起來在維生素,卡路里,礦物質等...

我想有很多不同的食物對象,我在我的應用程序和不同的功能,看着食物的不同方面,所以我實現了一個IFoodNutrition界面,使我的我希望與我的功能兼容的食品類實施它。然後我宣佈,我的功能將其作爲一個ARG

function GetRda(IFoodNutrition $food){} 

在C#中我將指定所有我需要的接口來使用,所以我知道實現,這將是與此功能兼容的任何類中的屬性。

讓我頭疼的是PHP只允許接口中的方法簽名。

我的問題顯然是範式轉變。我不確定PHP中的等效模式是什麼。我已閱讀文檔,除非從一個抽象類繼承,否則我不能看到類似的替代方法,但是隻能從一個類繼承,因此不能以相同的方式工作。

由於PHP不是類型安全的,我不必創建接口。有人可以發送任何對象到該方法,如果它具有正確的格式所需的屬性,它將工作。這對我來說看起來不太合適,但我習慣於在界面中展示事物應該如何交互。

我覺得應該至少是在對象進行驗證中間,一些明顯的結構,開發者可以看看,然後直觀地實現自己的階級和運行之前發現錯誤一些額外的步驟。

PHP中是否有這樣的特定模式?

+1

PHP(自版本5.1開始)允許[對象,數組,接口和可調用類型的提示](http://php.net/manual/en/language.oop5.typehinting.php),不僅用於接口。 [有向PHP 7提供標量類型提示的建議](https://wiki.php.net/rfc/scalar_type_hints),但它被撤消了。目前,沒有安全的方法來確保PHP中的類型安全。記錄可接受的參數類型,如果可能的話使用類型提示,並檢查函數是否獲得了預期的類型並相應地拋出異常。 – Carsten

回答

6

PHP只允許在接口方法簽名。

這是真實的。然而,沒有什麼能阻止你將屬性作爲接口的一部分製作傳統的getter和setter。這樣做會抽象出底層的實現細節。

有人可以發送任何對象的方法,如果它具有正確的格式所需的屬性,它將工作。

這是不正確的。您有type-hintedIFoodNutrition $food的爭執。如果這個函數收到一個沒有實現接口IFoodNutrition的對象,PHP會拋出一個致命錯誤。

+1

在無效類型上引發錯誤不會使語言類型安全。 7將朝着這一目標邁進很長一段路,但仍然不會安全。爲此,您需要在轉換等方面具有更多的可預測性。 – ircmaxell

+0

@ircmaxell,您瞭解了有關* type-safe *的語義。關於這個問題,*有人可以發送任何對象的方法,如果它具有所需的屬性在正確的格式,它將工作。*仍然是不正確的。 –

+0

當然,這就是爲什麼我沒有倒下或寫我自己的答案。你說的是點,只是語義細節稍微偏離,所以我通過解釋評論中的迂腐點來嘗試幫助。 :-D – ircmaxell

0

我的PHP知識仍然有限,但我會嘗試約我將如何解決這個問題的夫婦的答案。

1.快速和骯髒的(不推薦,恕我直言,大禁忌)

接受一切輸入,失敗的異常,如果輸入的是無效的。

 
    function getRda ($food) { 

     if (!($food instanceof IInterface)) { 
      throw new \Exception('function argument should be instance of IInterface'); 

     } 

    //... do your magic 
    } 

2.通過界面

在接口建議getter和setter,提供一個屬性的存在(例如getMinerals爲$礦物質)

3.使用的性狀

雖然在建立對象交互之間的協議方面它不會幫助你很多,但它會幫助你保持代碼乾燥。

trait Food 
{ 
    protected $minerals; 
    public function getMinerals() 
    { 
     return $this->minerals; 
    } 
} 

然後,在每一個類你想多繼承,使用上述特徵(的,比方說,延長了兩個抽象類的等價物)。

+0

你可以使用性狀屬性? – Guerrilla

+0

是的,當然是:http://php.net/manual/en/language.oop5.traits.php –

+0

對於提到特質,做'function getRda(IInterface $ food)' –

0

您無法在php中定義接口中的屬性。

它是有道理的,因爲接口的功能是指定一個API,而不是實現。