मेरे पास दो नियंत्रक SubmitPerformanceController
और हैं PrintReportController
।
में PrintReportController
मुझे एक विधि कहा जाता है getPrintReport
।
इस पद्धति का उपयोग कैसे करें SubmitPerformanceController
?
मेरे पास दो नियंत्रक SubmitPerformanceController
और हैं PrintReportController
।
में PrintReportController
मुझे एक विधि कहा जाता है getPrintReport
।
इस पद्धति का उपयोग कैसे करें SubmitPerformanceController
?
जवाबों:
आप इस तरह से अपनी कंट्रोलर विधि का उपयोग कर सकते हैं:
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
) में कॉल कर सकते हैं
आप लक्षणों के बारे में अधिक यहाँ पढ़ सकते हैं ।
app('App\Http\Controllers\PrintReportController')->getPrintReport();
में तब्दील हो सकता है app(PrintReportController::class')->getPrintReport()
। मेरे लिए स्वच्छ समाधान।
यदि आपको किसी अन्य नियंत्रक में उस विधि की आवश्यकता है, तो इसका मतलब है कि आपको इसे सार करने और इसे पुन: उपयोग करने की आवश्यकता है। उस कार्यान्वयन को एक सेवा वर्ग (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
}
}
अन्य नियंत्रकों के लिए भी वही करें जहाँ आपको उस कार्यान्वयन की आवश्यकता है। अन्य नियंत्रकों से नियंत्रक विधियों के लिए पहुंचना एक कोड गंध है।
Services
फ़ोल्डर अगर प्रोजेक्ट बड़ा नहीं है या एक फीचर फ़ोल्डर है जिसे कॉल किया जाता है Reporting
अगर यह एक बड़ा प्रोजेक्ट है और Folders By Feature
संरचना का उपयोग करता है।
किसी अन्य नियंत्रक से नियंत्रक को बुलाने की अनुशंसा नहीं की जाती है, हालाँकि यदि किसी भी कारण से आपको यह करना है, तो आप यह कर सकते हैं:
लारवेल 5 संगत विधि
return \App::call('bla\bla\ControllerName@functionName');
नोट: यह पृष्ठ के URL को अपडेट नहीं करेगा।
इसके बजाय रूट को कॉल करना बेहतर है और इसे नियंत्रक को कॉल करने दें।
return \Redirect::route('route-name-here');
आपको नहीं करना चाहिए यह एक विरोधी पैटर्न है। यदि आपके पास एक नियंत्रक में एक विधि है जिसे आपको दूसरे नियंत्रक में एक्सेस करने की आवश्यकता है, तो यह एक संकेत है जिसे आपको फिर से कारक करने की आवश्यकता है।
सेवा वर्ग में विधि को फिर से फैक्टर करने पर विचार करें, ताकि आप बाद में कई नियंत्रकों में त्वरित कर सकें। इसलिए यदि आपको कई मॉडलों के लिए प्रिंट रिपोर्ट देने की आवश्यकता है, तो आप कुछ ऐसा कर सकते हैं:
class ExampleController extends Controller
{
public function printReport()
{
$report = new PrintReport($itemToReportOn);
return $report->render();
}
}
\App::call('App\Http\Controllers\MyController@getFoo')
सबसे पहले, किसी अन्य नियंत्रक से नियंत्रक की एक विधि का अनुरोध ईवीआईएल है। यह लारवेल के जीवन-चक्र में कई छिपी हुई समस्याओं का कारण बनेगा।
वैसे भी, ऐसा करने के लिए कई समाधान हैं। आप इन विभिन्न तरीकों में से एक का चयन कर सकते हैं।
लेकिन आप इस तरह से कोई पैरामीटर या प्रमाणीकरण नहीं जोड़ सकते ।
app(\App\Http\Controllers\PrintReportContoller::class)->getPrintReport();
आप इसके साथ कोई भी पैरामीटर और कुछ जोड़ सकते हैं । आपके प्रोग्रामिंग जीवन के लिए सबसे अच्छा समाधान। आप 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 ...
}
}
MakesHttpRequests
एप्लिकेशन यूनिट टेस्टिंग में उपयोग होने वाले विशेषता का उपयोग करें ।मैं इसे सुझाता हूं यदि आपके पास इस प्रॉक्सी को बनाने का विशेष कारण है, तो आप किसी भी पैरामीटर और कस्टम हेडर का उपयोग कर सकते हैं । इसके अलावा यह लार्वा में एक आंतरिक अनुरोध होगा । (फेक एचटीटीपी रिक्वेस्ट) आप यहांcall
विधि के लिए अधिक विवरण देख सकते हैं ।
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 ...
}
}
हालाँकि यह 'अच्छा' समाधान नहीं है।
मुझे लगता है कि यह सबसे भयानक समाधान है। आप किसी भी पैरामीटर और कस्टम हेडर का भी उपयोग कर सकते हैं । लेकिन यह एक बाहरी अतिरिक्त http अनुरोध कर रहा होगा। तो HTTP वेबसर्वर चलना चाहिए।
$client = new Client([
'base_uri' => request()->getSchemeAndhttpHost(),
'headers' => request()->header()
]);
$a = $client->get('/performance/submit')->getBody()->getContents()
अंत में मैं केस 2 के मार्ग 1 का उपयोग कर रहा हूं। मुझे मापदंडों और की आवश्यकता है
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();
}
}
आप 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();
}
}
यह दृष्टिकोण नियंत्रक फ़ाइलों के समान पदानुक्रम के साथ भी काम करता है:
$printReport = new PrintReportController;
$prinReport->getPrintReport();
यहाँ विशेषता पूरी तरह से लार्वा राउटर (बिचौलियों और निर्भरता इंजेक्शन के समर्थन सहित) द्वारा चलने वाले नियंत्रक का अनुकरण करती है। केवल 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()->make(......)
समान है app(......)
इसलिए यह छोटा है।
आप इसे इंस्टेंट करके कंट्रोलर को कॉल कर सकते हैं और doAction: ( 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 में वापस पूरे रास्ते की आवश्यकता थी, अब यह बहुत सरल है।