2014-02-22 52 views
0

由於Php原生不允許擴展多個類,因此我使用laravel模型與數據進行交互並希望使用2個不同的包來擴展它的功能。在Laravel中擴展多個類

我試圖使用Ardent驗證程序和Revisionable維護更新歷史,但我不知道如何擴展這兩個類在我的模型。

任何幫助將不勝感激。

回答

0

正如你所說,PHP不支持多繼承,所以你沒有太多的選擇。儘管醜陋,但您可能不得不採取諸如this之類的措施,該措施使用__call()魔法。

+0

這會讓laravel難以想像 –

0

如您所知,PHP不支持多重繼承,不幸的是,這是一個PHP缺陷,也是一個由熱心和可修改軟件包開發人員創建的問題。以Sentry爲例,你可以使用任何你想要的雄辯實現,你只需在config.php中設置你需要的那個。不幸的是拉拉維爾的手綁在一起,因爲它是所有這些包的基類。我的想法是。

所以,你有一些選擇:

1)兩種封裝的Git庫文件中的問題,並希望他們的一個改變,不僅從\口才支持繼承,但任何用戶的等級,延長雄辯型號抽象類。

您甚至可以更改其中一個包的代碼,並向存儲庫發送拉取請求。如果這是一個很好的改變,你可能會看到它發生。

2)使用存儲庫模式,通過創建一個擴展自Eloquent的類,將兩個包作爲依賴關係,並在其內部從這些包中調用任何需要的東西。這不會是小菜一碟,因爲Eloquent是一個複雜的類,如果使用__call(),則必須映射所有需要轉發到包的方法,因此您不會冒險破壞Eloquent自己的動態調用:

use Ardent; 
use Revisionable; 

class User extends Eloquent { 

    private $ardent; 

    privave $revisionable; 

    public function __construct(Ardent $ardent, Revisionable $revisionable) 
    { 
     $this->ardent = $ardent; 

     $this->revisionable = $revisionable; 
    } 

    public function doWhatever() 
    { 
     return $this->ardent->do(); 
    } 

    public function __call($name, $arguments) 
    { 
     if($this->isArdentMethod($name)) 
     { 
      return call_user_func_array(array($this->ardent,$name), $arguments); 
     } 
     else 
     if($this->isRevisionableMethod($name)) 
     { 
      return call_user_func_array(array($this->revisionable,$name), $arguments); 
     } 
     else 
     { 
      return parent::__call($name, $arguments); 
     } 
    } 
} 

注意,這個調用

return parent::__call($name, $arguments); 

確保所有您的通話將被重定向到您的口才類,如果他們的目的不是由別人的一個執行。

由於事實上,你甚至可以選擇其中的一個,像熾熱的主類:

class User extends Ardent {} 

,只是有revisionable作爲一個依賴:

public function __construct(Revisionable $revisionable) 

再往前剛可修改的調用注入的依賴項。因爲,最終,這些類都是雄辯的,你可以有許多Eloquent模型指向相同的表。

如果你看一下Revisionable的源代碼,你會發現你真的必須考慮的唯一的調用是save(),因爲它覆蓋了Eloquent,所有其他的你可以調用Ardent的。

我知道這聽起來有點太多了,但它是可行的。

+0

是的,這是問題,因爲拉拉維爾在幕後做了很多事情,這將成爲真正的混亂,我將開始使用關係 –

+0

如果您映射熱心和/或可修改的方法你使用。這些類是由雄辯組成的,從一個或另一個調用一個方法不會產生任何影響,當然,除非它不是一個雄辯的方法。 –

+0

在可修改版本中提交了一個問題:https://github.com/VentureCraft/revisionable/issues/36 –

1

我最近在製作可修改的特性方面做了大量的工作。

所以,你就可以use,就像這樣:

class User extends Ardent { 
    use \Venturecraft\Revisionable\RevisionableTrait; 
} 

這是目前在Dev分支,但我喜歡一些幫助測試以前被合併脈澤:

https://github.com/VentureCraft/revisionable/issues/36

[編輯]這是現在在主分支,並可供公衆使用。

+0

當然,我會檢查它,並會開始玩它,因爲我有一個在我腦海中的實時想法,我可以測試它的所有情況下,並會報告回來的情況下,任何問題 –

+0

太棒了,有相當多的線程正在進行在那個github問題中,請隨時加入並加​​入進來。希望這個新的實現也將'解決'這個問題。 – duellsy

+0

你過得怎麼樣? – duellsy