我有两个控制器SubmitPerformanceController和PrintReportController。
在PrintReportController中,我有一个叫做getPrintReport的方法。
如何在submitperformanceccontroller中访问此方法?
我有两个控制器SubmitPerformanceController和PrintReportController。
在PrintReportController中,我有一个叫做getPrintReport的方法。
如何在submitperformanceccontroller中访问此方法?
当前回答
你不应该。这是反模式。如果你在一个控制器中有一个方法,你需要在另一个控制器中访问,那么这是你需要重构的标志。
考虑将方法重构到一个服务类中,然后可以在多个控制器中实例化该服务类。所以如果你需要为多个模型提供打印报告,你可以这样做:
class ExampleController extends Controller
{
public function printReport()
{
$report = new PrintReport($itemToReportOn);
return $report->render();
}
}
其他回答
当然,你可以实例化另一个控制器并调用你想要的方法。也许这不是一个好的做法,但我不知道为什么:
$otherController = new OtherController();
$otherController->methodFromOtherController($param1, $param2 ...);
但是,这样做,你会有一个问题:另一个方法返回类似response()->json($result)的东西,这不是你想要的。 为了解决这个问题,定义另一个控制器的方法的第一个参数为:
public function methodFromOtherController(Request $request = null, ...
当你从主控制器调用methodFromOtherController时,你将把null作为第一个参数值:
$otherController = new OtherController();
$otherController->methodFromOtherController(null, $param1, $param2 ...);
最后,在methodFromOtherController方法的末尾创建一个条件:
public function methodFromOtherController(Request $request = null, ...)
{
...
if (is_null($request)) {
return $result;
} else {
return response()->json($result);
}
}
一旦Laravel在通过直接路由调用时设置$request,您就可以区分每种情况并返回相应的值。
你可以通过实例化它并调用doAction来访问控制器:(put use Illuminate\Support\Facades\App;在控制器类声明之前)
$controller = App::make('\App\Http\Controllers\YouControllerName');
$data = $controller->callAction('controller_method', $parameters);
还要注意,这样做将不会执行该控制器上声明的任何中间件。
尝试在SubmitPerformanceController中创建一个新的PrintReportController对象,并直接调用getPrintReport方法。
例如,假设我在SubmitPerformanceController中有一个名为“Test”的函数,然后我可以这样做:
public function test() {
$prc = new PrintReportController();
$prc->getPrintReport();
}
这里trait完全模拟了laravel路由器的运行控制器(包括对中间件和依赖注入的支持)。仅在5.4版本中测试
<?php
namespace App\Traits;
use Illuminate\Pipeline\Pipeline;
use Illuminate\Routing\ControllerDispatcher;
use Illuminate\Routing\MiddlewareNameResolver;
use Illuminate\Routing\SortedMiddleware;
trait RunsAnotherController
{
public function runController($controller, $method = 'index')
{
$middleware = $this->gatherControllerMiddleware($controller, $method);
$middleware = $this->sortMiddleware($middleware);
return $response = (new Pipeline(app()))
->send(request())
->through($middleware)
->then(function ($request) use ($controller, $method) {
return app('router')->prepareResponse(
$request, (new ControllerDispatcher(app()))->dispatch(
app('router')->current(), $controller, $method
)
);
});
}
protected function gatherControllerMiddleware($controller, $method)
{
return collect($this->controllerMidlleware($controller, $method))->map(function ($name) {
return (array)MiddlewareNameResolver::resolve($name, app('router')->getMiddleware(), app('router')->getMiddlewareGroups());
})->flatten();
}
protected function controllerMidlleware($controller, $method)
{
return ControllerDispatcher::getMiddleware(
$controller, $method
);
}
protected function sortMiddleware($middleware)
{
return (new SortedMiddleware(app('router')->middlewarePriority, $middleware))->all();
}
}
然后将它添加到类中并运行控制器。注意,依赖注入将与当前路由一起分配。
class CustomController extends Controller {
use RunsAnotherController;
public function someAction()
{
$controller = app()->make('App\Http\Controllers\AnotherController');
return $this->runController($controller, 'doSomething');
}
}
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();
}
}