这是错误的。控制器必须只负责一项职责:接收 http 请求,从模型中获取一些数据并将其传递给视图。如果您的控制器必须与另一个控制器“对话”,这可能是因为您正在处理它们上的数据,或者通过它们读取数据,而您不应该这样做,因为处理数据是模型而不是控制器的责任。
首先,看一下SOLID和Single responsibility 原则。如果你能买到Taylor Otwell 的书: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';
}
}
这仍然是错误的,但要好一些。
更好的是在数据存储库中处理您的数据,因此请查看存储库模式, 这个 Taylor 的视频将让您很好地了解如何操作。它谈论可测试性,但不仅如此,您可以创建域存储库并在其中混合两个或多个模型,并在一个类中处理来自这些模型的数据。使用存储库模式的代码看起来更像:
创建接口(合约):
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 容器实例化,并且在getInfoB
存储库使用这两个模型生成数据并将其传递回控制器的方法中。
这一切都来自领域驱动开发。域是一个复杂的模型,例如订单,它是使用来自订单、用户、商品、运输和付款表的数据构建的。如果没有所有这些信息,您的付款页面上就不会真正显示订单,因此您创建了一个订单存储库并将所有 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 会自动实例化你的类的一个实例,你不需要做任何其他事情来让它工作。