Larabel 5의 다른 컨트롤러로부터의 접근컨트롤러 방식

컨트롤러가 2개 있다SubmitPerformanceController그리고.PrintReportController.

PrintReportController나는 다음과 같은 방법을 가지고 있다.getPrintReport.

에서 이 메서드에 액세스하는 방법SubmitPerformanceController?



질문에 대한 답변



다음과 같이 컨트롤러 방식에 액세스할 수 있습니다.

app('AppHttpControllersPrintReportController')->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)

특징에 대한 자세한 내용은 여기를 참조하십시오.




다른 컨트롤러에서 이 방법이 필요한 경우 추상화하여 재사용할 수 있도록 해야 합니다.이 실장을 서비스 클래스(Reporting Service 등)로 이동하여 컨트롤러에 삽입합니다.

예:

class ReportingService {
public function getPrintReport()
{
// your implementation here.
} } // don't forget to import ReportingService at the top (use PathToClass) 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
} } 

이 실장이 필요한 다른 컨트롤러에 대해서도 같은 작업을 수행합니다.다른 컨트롤러로부터 컨트롤러 메서드를 입수하는 것은 코드 냄새입니다.




다른 컨트롤러에서 컨트롤러를 호출하는 것은 권장되지 않지만 어떤 이유로든 호출해야 하는 경우 다음과 같이 할 수 있습니다.

Larabel 5 호환 방식

return App::call('blablaControllerName@functionName'); 

주의: 페이지 URL은 갱신되지 않습니다.

대신 Route에 전화를 걸어 컨트롤러에 전화를 걸도록 하는 것이 좋습니다.

return Redirect::route('route-name-here'); 



우선 다른 컨트롤러에 컨트롤러 방식을 요구하는 것은 EVAL이다.이것은 라라벨의 생애 주기에 많은 숨겨진 문제들을 야기할 것이다.

어쨌든, 그것을 하기 위한 많은 해결책이 있습니다.이러한 다양한 방법 중 하나를 선택할 수 있습니다.

케이스 1) 클래스에 따라 콜하는 경우

방법 1) 간단한 방법

그러나 이 방법으로는 매개 변수나 인증을 추가할 없습니다.

app(AppHttpControllersPrintReportContoller::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) 사용MakesHttpRequests응용 프로그램 유닛 테스트에서 사용된 특성입니다.

이 프록시를 만드는 특별한 이유가 있다면 어떤 파라미터와 커스텀헤더를 사용해도 좋습니다.또한 이것은 라라벨의 내부 요청입니다. (Fake HTTP Request) 자세한 내용은call메서드가 여기에 있습니다.

class SubmitPerformanceController extends AppHttpControllersController {
use IlluminateFoundationTestingConcernsMakesHttpRequests;
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 웹 서버가 실행 중이어야 합니다.

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



그러면 안 돼요.안티 패턴이에요.한 컨트롤러에 다른 컨트롤러에 액세스해야 하는 메서드가 있는 경우 이는 재계수가 필요한 신호입니다.

메서드를 서비스 클래스로 재팩터화하는 것을 검토해 주십시오.이러한 메서드는 여러 컨트롤러로 인스턴스화할 수 있습니다.따라서 여러 모델에 대해 인쇄 보고서를 제공해야 하는 경우 다음과 같은 작업을 수행할 수 있습니다.

class ExampleController extends Controller {
public function printReport()
{
$report = new PrintReport($itemToReportOn);
return $report->render();
} }