這是不對的。控制器必須承擔一項責任:接收http請求,從模型中獲取一些數據並將其傳遞給視圖。如果您的控制器必須與另一個控制器「交談」,可能是因爲您正在處理數據或通過它們讀取數據,而您不應該因爲處理數據而是模型而不是控制器的責任。
首先,看看SOLID和Single responsibility principle。如果你可以購買Taylor Otwell's book: Laravel: From Apprentice To Artisan,那麼,它會給你一個關於如何在Laravel實現SOLID原則的好主意。
然後,如果你真的需要在兩個不同的控制器上使用一個方法,創建一個新的類並在這兩個控制器上使用這個類。只是重構你的代碼做這樣的事情:
class MyController1 extends Controller {
public function __construct(MyClass $class)
{
$this->myClass = $class;
}
public function store()
{
$this->myClass->doWhatever();
}
}
class MyController2 extends Controller {
public function __construct(MyClass $class)
{
$this->myClass = $class;
}
public function update()
{
$this->myClass->doWhatever();
}
}
class MyClass {
public function doWhatever()
{
return 'done';
}
}
這仍然是錯誤的,但好一點。
更好的是在數據存儲庫中處理數據,所以看看存儲庫模式,this Taylor's video會給你一個很好的想法。它討論可測試性,但不僅如此,您可以創建域存儲庫並在其中混合兩個或更多模型,並在一個類中處理來自這些模型的數據。使用資源庫模式A的代碼將looke更像:
創建接口(合同):
interface MyDataRepository {
public function getInfoA();
public function getInfoB($dataA);
}
創建一個實現該接口
class MyData implements MyDataRepository {
public function __construct(MyModelA $dataA, MyModelB $dataB)
{
$this->dataA = $dataA;
$this->dataB = $dataB;
}
public function getInfoA()
{
return $this->dataA->processData();
}
public function getInfoB($dataA)
{
return $this->dataB->processData($this->getInfoA());
}
}
[編輯]
一個類
將存儲庫視爲一個包,您可以在其中放置所需的所有內容,並從中提取所需的內容。
在此存儲庫中,我們使用2個模型(MyModelA和MyModelB),通過Laravel的IoC容器實例化,在方法中,存儲庫正在使用這兩個模型生成數據並將其傳遞迴控制器。
這一切都來自域驅動開發。域是一個複雜的模型,如Order,它是使用來自訂單,用戶,項目,出貨和付款表的數據構建的。如果沒有所有這些信息,您就沒有訂單顯示在您的付款頁面上,因此您創建了一個訂單倉庫,並將您的所有ORM混合到一個類中,只有一個單一的功能來從這些表中獲取數據並將其發送回你的控制器。
[/編輯]
你必須告訴Laravel實例化類時,它需要你的接口的實例:
App::bind('MyDataRepository', 'MyData ');
當您使用的接口這只是做,在這裏我們使用的是具體的類做同樣的,我們並不需要告知什麼,Laravel知道該怎麼做:
public function __construct(MyClass $class)
{
$this->myClass = $class;
}
和使用存儲庫中創建你的控制器:
class MyController1 extends Controller {
public function __construct(MyDataRepository $data)
{
$this->data = $data;
}
public function store()
{
$this->data->getInfoA();
}
}
class MyController2 extends Controller {
public function __construct(MyDataRepository $class)
{
$this->data = $data;
}
public function update()
{
$this->myClass->getInfoB();
}
}
Laravel會自動實例化類的實例,你不需要做別的事,使其工作。
我不明白在另一個使用控制器的行爲。如果許多控制器使用相同的方法,請將其包含在基本控制器中或爲其創建一個類,然後調用它。 – itachi
@itachi沒有太多的控制器,例如2個控制器想要使用完整的非靜態類。 – Webinan