我有两个控制器SubmitPerformanceController和PrintReportController。
在PrintReportController中,我有一个叫做getPrintReport的方法。
如何在submitperformanceccontroller中访问此方法?
我有两个控制器SubmitPerformanceController和PrintReportController。
在PrintReportController中,我有一个叫做getPrintReport的方法。
如何在submitperformanceccontroller中访问此方法?
当前回答
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();
}
}
其他回答
这里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');
}
}
你可以像这样访问你的控制器方法:
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中映射它)
你可以在这里阅读更多关于特质的内容。
如果您在另一个控制器中需要该方法,这意味着您需要抽象它并使其可重用。将该实现移动到服务类(ReportingService或类似的东西)并将其注入到控制器中。
例子:
class ReportingService
{
public function getPrintReport()
{
// your implementation here.
}
}
// don't forget to import ReportingService at the top (use Path\To\Class)
class SubmitPerformanceController extends Controller
{
protected $reportingService;
public function __construct(ReportingService $reportingService)
{
$this->reportingService = $reportingService;
}
public function reports()
{
// call the method
$this->reportingService->getPrintReport();
// rest of the code here
}
}
对需要该实现的其他控制器执行相同的操作。从其他控制器中获取控制器方法是一种代码气味。
尝试在SubmitPerformanceController中创建一个新的PrintReportController对象,并直接调用getPrintReport方法。
例如,假设我在SubmitPerformanceController中有一个名为“Test”的函数,然后我可以这样做:
public function test() {
$prc = new PrintReportController();
$prc->getPrintReport();
}
晚回复,但我一直在寻找这个时间。这现在可以用一种非常简单的方式实现。
如果没有参数
return redirect()->action('HomeController@index');
与参数
return redirect()->action('UserController@profile', ['id' => 1]);
文档:https://laravel.com/docs/5.6/responses # redirecting-controller-actions
在5.0中,它需要完整的路径,现在它简单多了。