Laravel 4 - 在其他控制器中使用控制器动作?

Web*_*nan 2 php oop laravel laravel-4

好吧,我有几个控制器正在做我的工作,现在我创建了一些控制器; 在新控制器的动作中间,我只记得我在旧控制器中编写了正确的代码.

所以例如在oldController @ handyAction中

some_good_codez();
Run Code Online (Sandbox Code Playgroud)

并在newController @ newAction中

$myOldController = Load::controller('oldController'); // I wish Laravel had this?
$myOldController->handyAction();
Run Code Online (Sandbox Code Playgroud)

Ant*_*iro 9

这是错的.控制器只需要承担一项责任:接收http请求,从模型中获取一些数据并将其传递给视图.如果您的控制器必须与另一个控制器"对话",那可能是因为您正在处理它们上的数据,或者通过它们读取数据而您不应该因为处理数据而不是模型而不是控制器.

首先,看看SOLIDSingle责任原则.如果你能买到Taylor Otwell的书:Laravel:从Apprentice到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';
    }

}
Run Code Online (Sandbox Code Playgroud)

这仍然是错误的,但更好一点.

更好的是在数据存储库中处理您的数据,所以看看存储库模式, 这个泰勒的视频将让您对如何做到这一点有一个很好的了解.它谈论的可测性,但它不只是这一点,你可以创建站点库和两个或多个模型里面和处理数据,这些模型在一个类中混合.使用Repository模式的代码更像是:

创建一个接口(合同):

interface MyDataRepository {

    public function getInfoA();
    public function getInfoB($dataA);

}
Run Code Online (Sandbox Code Playgroud)

创建一个实现此接口的类

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() );
    }

}
Run Code Online (Sandbox Code Playgroud)

[编辑]

将存储库视为一个包,您可以在其中放置所需的一切并从中提取所需内容.

在这个存储库中,我们使用2个模型(MyModelA和MyModelB),由Laravel的IoC容器实例化,并且在该方法中getInfoB,存储库使用它们来生成数据并将其传递回控制器.

这一切都来自Domain Driven Development.域是一个复杂的模型,如Order,它使用来自订单,用户,物品,发货和付款表的数据构建.如果没有所有这些信息,您实际上没有订单显示在您的付款页面上,因此您创建了一个订单存储库并将所有ORM混合在一个类中,它具有从这些表中获取数据并将其发送回的唯一可靠性.你的控制器.

[/编辑]

当需要一个接口实例时,你必须告诉Laravel实例化该类:

App::bind('MyDataRepository', 'MyData ');
Run Code Online (Sandbox Code Playgroud)

只有在使用接口时才会这样做,这里我们使用具体的类做同样的事情,我们不需要通知任何东西,Laravel知道该怎么做:

public function __construct(MyClass $class)   
{
    $this->myClass = $class;
}
Run Code Online (Sandbox Code Playgroud)

并使用存储库创建控制器:

    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();
    }

}
Run Code Online (Sandbox Code Playgroud)

Laravel将自动实例化您的类的实例,您不需要做任何其他事情来使其工作.