Laravel 4-在其他控制器中使用控制器动作? [英] Laravel 4 - Use a controller action in other controllers?

查看:70
本文介绍了Laravel 4-在其他控制器中使用控制器动作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我有几个正在执行工作的控制器,现在我又创建了一些控制器.在新控制器中某个动作的中间,我只是记得我已经在旧控制器中编写了正确的代码.

well I had a few controllers that were doing my jobs, now I created a few more controllers; some where in middle of an action in new controller, I just remembered that I've written the proper code in old controllers.

例如在oldController @ handyAction

so for e.g. in oldController@handyAction

some_good_codez();

和在newController @ newAction

and in newController@newAction

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

推荐答案

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

This is wrong. Controllers have to have just one responsibility: receive a http request, get some data from your models and pass it away to a view. If your controllers have to 'talk' with another controller, it's probably because you're processing data on them, or reading data through them and you shouldn't because to process data is the responsibility of models not controllers.

首先,看看 SOLID 单一责任原则.如果您可以购买泰勒·奥特威尔(Taylor Otwell)的书:《拉拉威尔(Laravel):从学徒到工匠》 ,这样做会给您一个好主意如何在Laravel中实现SOLID原则.

First, take a look at SOLID and Single responsibility principle. If you can buy Taylor Otwell's book: Laravel: From Apprentice To Artisan, do it, it will give you a good idea of how to implement SOLID principles in Laravel.

然后,如果您确实需要在两个不同的控制器上使用一个方法,请创建一个新类,并在两个控制器上都使用该类.只需重构代码即可执行以下操作:

Then, if you really need to use a method on two different controllers, create a new class and use this class on both controllers. Just refactor your code to do something like this:

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 is still wrong, but a little better.

更好的是在数据存储库中处理数据,因此请查看存储库模式,此Taylor的视频将为您提供一个很好的想法.它讨论了可测试性,但不仅限于此,您还可以创建域存储库并在其中混合两个或多个模型,并在一类中处理这些模型中的数据.使用存储库"模式的代码看起来更像:

What's even better is to process your data in a data repository, so take a look at the Repository Pattern, this Taylor's video will give you a nice idea of how you do it. It talks about testability, but it's not just that, you can create domain repositories and mix two or more models inside it and process data from those models in one class. A code using the Repository pattern would looke more like:

创建界面(合同):

interface MyDataRepository {

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

}

创建一个实现此接口的类

Create a class that implements this interface

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

}

将存储库看作一个袋子,您可以在其中放置所需的所有内容并从中提取所需的内容.

Think of a repository as a bag, where you can put everything you need and extract what you need from it.

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

In this repository we are using 2 models (MyModelA e MyModelB), instantiated by the Laravel's IoC Container, and in the method getInfoB the repository is using both to generate data and pass it back to the controller.

这一切都来自域驱动开发.域是一个复杂的模型,例如订购,它是使用来自订购,用户,物料,运输和付款表的数据构建的.没有所有这些信息,您的付款页面上实际上就不会显示订单,因此您将创建一个订单存储库并将所有ORM混合在一个类中,这具有单一的可再用性,可以从这些表中获取数据并将其发送回您的控制器.

This all come from Domain Driven Development. A Domain is a complex model, like Order, that's built using data from orders, users, items, shippings and payments tables. Without all this information you don't really have an Order to show on your payment page, so you create an Order Repository and mix all your ORM in one class, wich has the single resposibility to get data from those tables and send it back to your controller.

[/edit]

您必须告诉Laravel在需要接口实例的情况下实例化该类:

You'll have to tell Laravel to instantiate that class when it needs an instance of your Interface:

App::bind('MyDataRepository', 'MyData ');

仅当您使用接口时才执行此操作,这里我们使用具体的类进行此操作,并且我们不需要通知任何信息,Laravel知道该怎么做:

This is done only when you are using interfaces, here we are doing the same using a concrete class and we don't need to inform anything, Laravel knows what to do:

public function __construct(MyClass $class)   
{
    $this->myClass = $class;
}

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

And create your controllers using the repository:

    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将自动实例化您的类的实例,您无需执行任何其他操作即可使其工作.

Laravel will automatically instantiate an instance of your class, you don't need to do anything else to make it work.

这篇关于Laravel 4-在其他控制器中使用控制器动作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆