লারাভেল 5-এ অন্য নিয়ামকের কাছ থেকে অ্যাক্সেস কন্ট্রোলার পদ্ধতি


161

আমার দু'জন কন্ট্রোলার SubmitPerformanceControllerএবং PrintReportController

ইন PrintReportControllerআমি একটি পদ্ধতি বলা আছে getPrintReport

এই পদ্ধতিতে কীভাবে অ্যাক্সেস করবেন SubmitPerformanceController?

উত্তর:


363

আপনি আপনার নিয়ামক পদ্ধতিটি এর মধ্যে অ্যাক্সেস করতে পারেন:

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)

আপনি এখানে বৈশিষ্ট্য সম্পর্কে আরও পড়তে পারেন ।


10
বৈশিষ্ট্য সহ ফাইলটি কোথায় সংরক্ষণ করা উচিত?
ব্রেনম্যানিয়াক

24
app('App\Http\Controllers\PrintReportController')->getPrintReport();রূপান্তর করতে পারেন app(PrintReportController::class')->getPrintReport()। আমার জন্য পরিষ্কার সমাধান।
ভিনসেন্ট ডেকাউস

বৈশিষ্ট্য ফাইলটি কোথায় সঞ্চয় হয়?
এরিক ম্যাকউইননার

অনুমান করুন অ্যাপ \ বৈশিষ্ট্যগুলির মতো এটিই আপনার এমিরিক এমকিউইনএনইআর এটি আপনার যে কোনও জায়গায় সংরক্ষণ করা যেতে পারে। তবে সেই বৈশিষ্ট্যে যথাযথ নেমস্পেস ব্যবহার করা নিশ্চিত করুন।
ট্রাইব্যুনাল


48

আপনার যদি অন্য কোনও নিয়ামকের কাছে সেই পদ্ধতিটির প্রয়োজন হয়, তার অর্থ আপনার এস্ট্রাক্ট করে এটিকে পুনরায় ব্যবহারযোগ্য করে তোলা দরকার। সেই বাস্তবায়নটিকে কোনও পরিষেবা শ্রেণিতে (রিপোর্টিংসেবা বা এর অনুরূপ কিছু) সরান এবং এটিকে আপনার নিয়ামকগুলিতে ইনজেক্ট করুন।

উদাহরণ:

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
  }
}

অন্যান্য নিয়ন্ত্রকদের যেখানে আপনার সেই বাস্তবায়ন প্রয়োজন সেখানে একই কাজ করুন। অন্যান্য নিয়ন্ত্রকদের কাছ থেকে নিয়ামক পদ্ধতির জন্য পৌঁছানো একটি কোড গন্ধ।


প্রকল্প কাঠামোর ক্ষেত্রে আপনি এই শ্রেণিটি কোথায় সংরক্ষণ করবেন?
অমিতায়ে

1
হয় Servicesযদি প্রকল্পটি বড় না হয় তবে কোনও ফোল্ডার বা Reportingকোনও বৃহত প্রকল্প এবং Folders By Featureকাঠামোগত ব্যবহার করে এমন বৈশিষ্ট্য ফোল্ডার বলা হয় ।
রাফেলস

আপনি কি এখানে পরিষেবা সরবরাহকারী (পরিষেবা শ্রেণি) হিসাবে উল্লেখ করছেন লারাভেল ডকস / /./ / প্রোভাইডার বা এখানে কোনও পরিষেবা কনটেইনার লারাভেল ডকস / ডকস / .7..7 / কনটেইনার ?
বাসপা

1
@ বাসপা নো, একটি সাধারণ পিএইচপি ক্লাস।
রাফেলস

27

অন্য কোনও নিয়ন্ত্রকের কাছ থেকে একটি কন্ট্রোলারকে কল করার পরামর্শ দেওয়া হয় না, তবে যদি কোনও কারণে আপনার এটি করতে হয় তবে আপনি এটি করতে পারেন:

লারাভেল 5 সুসংগত পদ্ধতি

return \App::call('bla\bla\ControllerName@functionName');

দ্রষ্টব্য: এটি পৃষ্ঠার ইউআরএল আপডেট করবে না।

পরিবর্তে রুটটি কল করা এবং এটি নিয়ামককে কল করা ভাল।

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

2
কেন এটি সুপারিশ করা হয় না?
brunouno

এটি শীর্ষ উত্তর হওয়া উচিত।
জাস্টিন ভিনসেন্ট

13

আপনার উচিত হবে না। এটি একটি অ্যান্টি-প্যাটার্ন। আপনার যদি একটি নিয়ামকের এমন একটি পদ্ধতি থাকে যা আপনাকে অন্য নিয়ামকটিতে অ্যাক্সেস করতে হবে তবে এটি আপনাকে পুনরায় ফ্যাক্টর করার একটি চিহ্ন।

কোনও পরিষেবা শ্রেণিতে পদ্ধতিটি পুনরায় ফ্যাক্টরিংয়ের বিষয়টি বিবেচনা করুন, আপনি একাধিক কন্ট্রোলারে ইনস্ট্যান্ট করতে পারেন। সুতরাং আপনার যদি একাধিক মডেলের জন্য মুদ্রণ প্রতিবেদন সরবরাহ করার প্রয়োজন হয় তবে আপনি এরকম কিছু করতে পারেন:

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

10
\App::call('App\Http\Controllers\MyController@getFoo')

11
আপনার উত্তরটি সঠিক হতে পারে তা সত্ত্বেও, এটি কিছুটা প্রসারিত করে আরও কিছু ব্যাখ্যা দেওয়া ভাল লাগবে।
স্কানা

9

প্রথমত, অন্য নিয়ামকের কাছ থেকে একটি নিয়ামকের পদ্ধতির অনুরোধ করা হ'ল ইভিএল। এটি লারাভেলের জীবনচক্রটিতে অনেক লুকানো সমস্যা সৃষ্টি করবে।

যাইহোক, এটি করার জন্য অনেকগুলি সমাধান রয়েছে। আপনি এই বিভিন্ন উপায়ে একটি নির্বাচন করতে পারেন।

কেস 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) 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 ...
    }
}

তবে এটিও 'ভাল' সমাধান নয়।

উপায় 2) গুজলেহট্টপ ক্লায়েন্ট ব্যবহার করুন

এটি আমার মনে হয় সবচেয়ে ভয়ঙ্কর সমাধান। আপনি যে কোনও প্যারামিটার এবং কাস্টম শিরোনামও ব্যবহার করতে পারেন । তবে এটি একটি বাহ্যিক অতিরিক্ত http অনুরোধ করা হবে। সুতরাং এইচটিটিপি ওয়েবসার্ভার অবশ্যই চলমান।

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

অবশেষে আমি কেস 2 এর ওয়ে 1 ব্যবহার করছি আমার প্যারামিটারগুলি দরকার এবং


1
ওয়ে 2 সেখানে লেখা উচিত নয়, আপনি নিজেরাই নিজেই http- অনুরোধ করতে চান না, এমনকি কোনও খারাপ কোড কাঠামোতেও।
Sw0ut

5
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();   
    }
   }

7
আরও তথ্যের সাথে সম্পাদনা করুন। কেবল-কোড এবং "এটি চেষ্টা করুন" উত্তরগুলি নিরুৎসাহিত করা হয়েছে, কারণ সেগুলিতে কোনও অনুসন্ধানযোগ্য সামগ্রী নেই এবং কারও "কেন এটি চেষ্টা করা উচিত" তা ব্যাখ্যা করবেন না।
অ্যারিসোন

2

আপনি প্রিন্টরেপোর্টকন্ট্রোলারে একটি স্ট্যাটিক পদ্ধতি ব্যবহার করতে পারেন এবং তারপরে এটিকে সাবমিটফরম্যান্স কন্ট্রোলার থেকে কল করতে পারেন;

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();

    }

}

2

এই পদ্ধতিটি একই নিয়ন্ত্রক ফাইলগুলির শ্রেণিবিন্যাসের সাথেও কাজ করে:

$printReport = new PrintReportController;

$prinReport->getPrintReport();

আমি অ্যাপটির সাথে তুলনা করে এই পদ্ধতিকে পছন্দ করি :: একটি করুন কারণ ডক ব্লকের টাইপ ইঙ্গিতটি এইভাবে পিএইচপিস্টোরমে কাজ করে।
ফ্লোরিস

1

এখানে বৈশিষ্ট্যটি সম্পূর্ণভাবে ল্যারাভেল রাউটার (মিডলওয়্যার এবং নির্ভরতা ইনজেকশন সমর্থন সহ) দ্বারা চলমান নিয়ামককে পুরোপুরি অনুকরণ করে। শুধুমাত্র 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(......)তাই এটি খাটো হয়।
মাটিস্লৌরিটি

1

আপনি এটা শুরু করতে গিয়ে এবং doAction কল করে নিয়ামক অ্যাক্সেস করতে পারে: (করা use Illuminate\Support\Facades\App;নিয়ামক বর্গ ঘোষণা করার আগে)

$controller = App::make('\App\Http\Controllers\YouControllerName');
$data = $controller->callAction('controller_method', $parameters);

আরও মনে রাখবেন যে এটি করার মাধ্যমে আপনি সেই নিয়ামকের উপর ঘোষিত মিডলওয়্যারের কোনওটিই কার্যকর করবেন না।


-2

দেরীতে জবাব, তবে আমি এটি কিছু সময়ের জন্য সন্ধান করছি। এটি এখন খুব সহজ উপায়ে সম্ভব।

পরামিতি ছাড়াই

return redirect()->action('HomeController@index');

পরামিতি সহ

return redirect()->action('UserController@profile', ['id' => 1]);

দস্তাবেজ: https://laravel.com/docs/5.6/ দায়বদ্ধতা#redirecting-controller- tives

5.0 এ ফিরে এটি পুরো পথের প্রয়োজন, এখন এটি অনেক সহজ।


3
মূল প্রশ্নটি ছিল অন্যান্য নিয়ামকের কাছ থেকে কীভাবে কোনও নিয়ামকের পদ্ধতি অ্যাক্সেস করা যায়, কীভাবে অন্যান্য নির্দিষ্ট পদ্ধতির ক্রিয়াতে পুনর্নির্দেশ করা যায় না, সুতরাং আপনার সমাধান প্রশ্নের সাথে সম্পর্কিত নয়।
মাটিস্লৌরিটি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.