আমার দু'জন কন্ট্রোলার 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()
। আমার জন্য পরিষ্কার সমাধান।
আপনার যদি অন্য কোনও নিয়ামকের কাছে সেই পদ্ধতিটির প্রয়োজন হয়, তার অর্থ আপনার এস্ট্রাক্ট করে এটিকে পুনরায় ব্যবহারযোগ্য করে তোলা দরকার। সেই বাস্তবায়নটিকে কোনও পরিষেবা শ্রেণিতে (রিপোর্টিংসেবা বা এর অনুরূপ কিছু) সরান এবং এটিকে আপনার নিয়ামকগুলিতে ইনজেক্ট করুন।
উদাহরণ:
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');
দ্রষ্টব্য: এটি পৃষ্ঠার ইউআরএল আপডেট করবে না।
পরিবর্তে রুটটি কল করা এবং এটি নিয়ামককে কল করা ভাল।
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 অনুরোধ করা হবে। সুতরাং এইচটিটিপি ওয়েবসার্ভার অবশ্যই চলমান।
$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();
}
}
আপনি প্রিন্টরেপোর্টকন্ট্রোলারে একটি স্ট্যাটিক পদ্ধতি ব্যবহার করতে পারেন এবং তারপরে এটিকে সাবমিটফরম্যান্স কন্ট্রোলার থেকে কল করতে পারেন;
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();
}
}
এখানে বৈশিষ্ট্যটি সম্পূর্ণভাবে ল্যারাভেল রাউটার (মিডলওয়্যার এবং নির্ভরতা ইনজেকশন সমর্থন সহ) দ্বারা চলমান নিয়ামককে পুরোপুরি অনুকরণ করে। শুধুমাত্র 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/ দায়বদ্ধতা#redirecting-controller- tives
5.0 এ ফিরে এটি পুরো পথের প্রয়োজন, এখন এটি অনেক সহজ।