Laravel DI:调用控制器方法而不传递注入变量,是否可能?

Sec*_*Fry 5 php laravel

class SomeController extends Controller {

  public function doALot(Request $request) {

    $this -> doOne($someOtherVariable);
    // Type error: Argument 1 passed to App\Http\Controllers\SomeController::doOne() must be an instance of Illuminate\Http\Request

    $this -> doOne($request, $someOtherVariable);
    // Bad practice?
    ...
  }

  public function doOne(Request $request, $someOtherVariable) {}
  ...    
}
Run Code Online (Sandbox Code Playgroud)

那么如何doOne()doALot()不传递注入资源的情况下进行调用,但是已经Request进入doOne()?传遍$request整个地方感觉不好.

解决方案tl; dr不可能,但还有其他方法 - 阅读Alexey Mezenin的简短回答

长版(可能不是最好但足够).

$ php artisan make:provider SomeServiceProvider
Run Code Online (Sandbox Code Playgroud)

然后在创建的提供程序编辑中register()调用某些内容:

public
function register() {
    $this -> app -> bind('App\Services\SomeService', function ($app) {
        return new SomeService();
    });
}
Run Code Online (Sandbox Code Playgroud)

然后继续创建将资源注入属性的服务类.

<?php

namespace App\Services;

use \Illuminate\Support\Facades\Request;

class SomeService {
    private $request;

    /**
     * SomeService constructor.
     */
    public
    function __construct(Request $request) {
        $this -> request = $request;
    }

    public function doOne($someOtherVariable) {}
}
Run Code Online (Sandbox Code Playgroud)

然后将您的方法从控制器移动到服务,并将服务注入控制器.

权衡:( - )两个无用的文件来执行基本功能,(+)从控制器分离逻辑实现,(〜)可能更干净的代码.

Ale*_*nin 2

手动调用控制器操作不是一个好主意。业务逻辑应该在服务类中。您可以在我的 Laravel 最佳实践存储库中看到一个示例。如果您不想$request每次都传递对象,可以Request在服务类或控制器构造函数中注入类。

使用Request数据的另一种方法是使用request()助手:

request('key')
request()->has('key')
Run Code Online (Sandbox Code Playgroud)

Request门面:

Request::has('key')
Run Code Online (Sandbox Code Playgroud)

或者您可以手动将其注入方法内:

$request = app('Illuminate\Http\Request');
Run Code Online (Sandbox Code Playgroud)