컨트롤러가 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();
} }