在Laravel中从另一个控制器调用控制器是一种好习惯吗?

Oba*_*bay 5 php paypal laravel laravel-5.1

我能够PaypalController使用可重用的postPayment()方法实现,接受商品及其价格,并创建Paypal付款,然后重定向到Paypal付款页面。

class PaypalController extends Controller {

    private static $_api_context;

    private static function initialize() {
        //initialize api context
    }

    public static function postPayment($items, $currency, $description) {
        self::initialize();

        //create item list, transaction, payment objects, etc

        $payment->create(PaypalController::$_api_context);
        ...
        return redirect()->away($redirect_url); // redirect to paypal
    }
}
Run Code Online (Sandbox Code Playgroud)

PaypalController由其他控制器静态调用。例如,当AuthController用户注册到我的网站后, 可能会调用它来请求用户付款:

class AuthController extends Controller {
    public function postRegister(Request $request) {
        return PaypalController::postPayment($items, 'JPY', 'description');
    }
}
Run Code Online (Sandbox Code Playgroud)

基本上,PaypalController将返回RedirectAuthController,也将返回它,以执行重定向到Paypal付款页面的操作。

我想知道这是否是一个好的设计-一个控制器调用另一个控制器,对吗?

如果没有,哪种更好的方法呢?也许将我的代码从PaypalController移到自定义服务提供商,自定义助手或其他东西?我是Laravel的新手,希望能提供一些指导。

The*_*pha 3

不,这不是一个好的做法。您应该将业务逻辑抽象为服务/存储库类。例如:

创建一个接口作为合约:

namespace App\Services\Paypal;

interface PaypalInterface {

     public function PostRegister(Array $array, /*More $params if necessary*/); 
}
Run Code Online (Sandbox Code Playgroud)

然后执行合约:

namespace App\Services\Paypal;

class PaypalService implements PaypalInterface {

    // Must match the method signature declared in the interface
    public function PostRegister(Array $array, /*$More $params if necessary*/) {

        // Do the process here
    }
}
Run Code Online (Sandbox Code Playgroud)

然后使用契约/接口作为依赖。因此,在您PaypalController或任何其他控制器中,您可以(重新)使用它,如下所示:

namespace App\Http\Controllers;

use App\Http\Request;
use App\Services\Paypal\PaypalInterface;

class AuthController extends Controller {
    public function postPayment(Request $request, PaypalInterface $paypalService) {
        return $paypalService->postRegister($request->all());
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,在服务提供者中注册绑定(实现的接口)(基本上在AppServiceProvider)。这就是基本的工作流程。为什么要使用接口,因为控制器(客户端/消费者类)应该与合约/接口对话,而不是具体的实现。

我的这篇文章可能对您有帮助,但请记住这不是 100% 解耦,它仍然与Laravel框架耦合,您甚至可以进一步解耦服务。


注意:这是一种最佳实践,但不要对每个项目/问题都盲目地遵循这种方法,只需明智地选择何时应该这样做,这实际上取决于上下文,但不要为此而死。当前的背景可以很好地遵循这一点。

  • 这是解耦业务逻辑的正确/最佳实践,也就是说:针对接口编程,而不是针对具体实现编程。换句话说,对抽象类型(接口)的依赖使双方不会紧密解耦,并且即使不触及应用程序逻辑也可以改变依赖关系。但就像我说的,做你认为对自己更好的事情,不要遵循任何规则,直到你意识到需要并理解它。无论如何,它带来了话题。 (2认同)