我有两个控制器SubmitPerformanceController和PrintReportController。
在PrintReportController中,我有一个叫做getPrintReport的方法。
如何在submitperformanceccontroller中访问此方法?
我有两个控制器SubmitPerformanceController和PrintReportController。
在PrintReportController中,我有一个叫做getPrintReport的方法。
如何在submitperformanceccontroller中访问此方法?
当前回答
你可以像这样访问你的控制器方法:
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中映射它)
你可以在这里阅读更多关于特质的内容。
其他回答
首先,从另一个控制器请求一个控制器的方法是邪恶的。这将在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::call('App\Http\Controllers\MyController@getFoo')
你可以在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();
}
}
你可以通过实例化它并调用doAction来访问控制器:(put use Illuminate\Support\Facades\App;在控制器类声明之前)
$controller = App::make('\App\Http\Controllers\YouControllerName');
$data = $controller->callAction('controller_method', $parameters);
还要注意,这样做将不会执行该控制器上声明的任何中间件。
晚回复,但我一直在寻找这个时间。这现在可以用一种非常简单的方式实现。
如果没有参数
return redirect()->action('HomeController@index');
与参数
return redirect()->action('UserController@profile', ['id' => 1]);
文档:https://laravel.com/docs/5.6/responses # redirecting-controller-actions
在5.0中,它需要完整的路径,现在它简单多了。