我有两个控制器SubmitPerformanceController和PrintReportController。

在PrintReportController中,我有一个叫做getPrintReport的方法。

如何在submitperformanceccontroller中访问此方法?


当前回答

你可以在PrintReportController中使用一个静态方法,然后像这样从SubmitPerformanceController调用它;

namespace App\Http\Controllers;

class PrintReportController extends Controller
{

    public static function getPrintReport()
    {
      return "Printing report";
    }


}



namespace App\Http\Controllers;

use App\Http\Controllers\PrintReportController;

class SubmitPerformanceController extends Controller
{


    public function index()
    {

     echo PrintReportController::getPrintReport();

    }

}

其他回答

这种方法也适用于相同层次的Controller文件:

$printReport = new PrintReportController;

$prinReport->getPrintReport();

在我看来最优雅的方法是:

app(YourController::class)->yourControllerMethod()

首先,从另一个控制器请求一个控制器的方法是邪恶的。这将在Laravel的生命周期中造成许多隐藏的问题。

不管怎样,有很多解决方法。你可以从这些不同的方法中选择一种。

案例1)如果你想基于类调用

方法1)简单的方法

但是您不能用这种方式添加任何参数或身份验证。

app(\App\Http\Controllers\PrintReportContoller::class)->getPrintReport();

方法2)将控制器逻辑划分为服务。

你可以添加任何参数。这是您编程生涯的最佳解决方案。您可以使用Repository代替Service。

class PrintReportService
{
    ...
    public function getPrintReport() {
        return ...
    }
}

class PrintReportController extends Controller
{
    ...
    public function getPrintReport() {
        return (new PrintReportService)->getPrintReport();
    }
}

class SubmitPerformanceController
{
    ...
    public function getSomethingProxy() {
        ...
        $a = (new PrintReportService)->getPrintReport();
        ...
        return ...
    }
}

情况2)如果你想基于路由调用

1)使用应用单元测试中使用的makeshttprequest特性。

我建议,如果你有特殊的原因做这个代理,你可以使用任何参数和自定义头。这也将是laravel的内部要求。(假HTTP请求)你可以在这里看到调用方法的更多细节。

class SubmitPerformanceController extends \App\Http\Controllers\Controller
{
    use \Illuminate\Foundation\Testing\Concerns\MakesHttpRequests;
    
    protected $baseUrl = null;
    protected $app = null;

    function __construct()
    {
        // Require if you want to use MakesHttpRequests
        $this->baseUrl = request()->getSchemeAndHttpHost();
        $this->app     = app();
    }

    public function getSomethingProxy() {
        ...
        $a = $this->call('GET', '/printer/report')->getContent();
        ...
        return ...
    }
}

然而,这也不是一个“好的”解决方案。

方法2)使用guzzlehttp客户端

我认为这是最糟糕的解决方案。您还可以使用任何参数和自定义标头。但是这会产生一个外部额外的http请求。所以HTTP web服务器必须在运行。

$client = new Client([
    'base_uri' => request()->getSchemeAndhttpHost(),
    'headers' => request()->header()
]);
$a = $client->get('/performance/submit')->getBody()->getContents()

你可以像这样访问你的控制器方法:

app('App\Http\Controllers\PrintReportController')->getPrintReport();

这可以工作,但在代码组织方面很糟糕(记住为PrintReportController使用正确的名称空间)

你可以扩展PrintReportController,这样SubmitPerformanceController将继承这个方法

class SubmitPerformanceController extends PrintReportController {
     // ....
}

但这也会从PrintReportController继承所有其他方法。

最好的方法是创建一个trait(例如在app/Traits中),在那里实现逻辑,并告诉你的控制器使用它:

trait PrintReport {

    public function getPrintReport() {
        // .....
    }
}

告诉你的控制器使用这个特性:

class PrintReportController extends Controller {
     use PrintReport;
}

class SubmitPerformanceController extends Controller {
     use PrintReport;
}

这两种解决方案都使SubmitPerformanceController具有getPrintReport方法,因此您可以使用$this->getPrintReport()调用它;从控制器内部或直接作为路由(如果你在routes.php中映射它)

你可以在这里阅读更多关于特质的内容。

namespace App\Http\Controllers;

//call the controller you want to use its methods
use App\Http\Controllers\AdminController;

use Illuminate\Http\Request;

use App\Http\Requests;

class MealController extends Controller
   {
      public function try_call( AdminController $admin){
         return $admin->index();   
    }
   }