लारवेल मिडलवेयर नियंत्रक पर चर लौटाता है


87

मैं यह निर्धारित करने के लिए एक उपयोगकर्ता की अनुमति की जांच कर रहा हूं कि वे पृष्ठ देख सकते हैं या नहीं। इसमें पहले कुछ मिडलवेयर के माध्यम से अनुरोध पारित करना शामिल है।

मेरे पास जो समस्या है वह यह है कि मैं डेटा को वापस देखने से पहले मिडलवेयर और कंट्रोलर में एक ही डेटाबेस क्वेरी को डुप्लिकेट कर रहा हूं।

यहाँ सेटअप का एक उदाहरण है;

- मार्गों

Route::get('pages/{id}', [
   'as' => 'pages',
   'middleware' => 'pageUser'
   'uses' => 'PagesController@view'
]);

- PageUserMiddleware.php (वर्ग पृष्ठउपयोगकर्ता सॉफ्टवेयर)

public function handle($request, Closure $next)
    {
        //get the page
        $pageId = $request->route('id');
        //find the page with users
        $page = Page::with('users')->where('id', $pageId)->first();
        //check if the logged in user exists for the page
        if(!$page->users()->wherePivot('user_id', Auth::user()->id)->exists()) {
            //redirect them if they don't exist
            return redirect()->route('redirectRoute');
        }
        return $next($request);
    }

- PagesController.php

public function view($id)
{
    $page = Page::with('users')->where('id', $id)->first();
    return view('pages.view', ['page' => $page]);
}

जैसा कि आप देख सकते हैं, Page::with('users')->where('id', $id)->first()मिडिलवेयर और कंट्रोलर दोनों में दोहराया जाता है। मुझे डुप्लिकेट करने के लिए एक से दूसरे के माध्यम से डेटा पास करने की आवश्यकता है।


मैं उसी के बारे में पूछने जा रहा था, मुझे इसका उत्तर खोजने में बहुत समय लगा। यहाँ मेरा सवाल है। मैं इसे एसईओ / खोज योग्य कारणों के लिए यहां जोड़ूंगा, आशा है कि यह ठीक है: लारवेल 5.0 - मिडलवेयर और कंट्रोलर में लोड मॉडल। मैं उपयोगकर्ता मॉडल का एक उदाहरण कैसे लोड करूं ताकि मिडवेवेयर और कंट्रोलर दोनों में एक ही उदाहरण (केवल एक डेटाबेस क्वेरी) उपलब्ध हो? क्योंकि मिडलवेयर में मैं यह जांचना चाहता हूं कि क्या उपयोगकर्ता अधिकृत है और नियंत्रक में मैं उपयोगकर्ता के बारे में जानकारी प्रस्तुत करना चाहता हूं या किसी तरह उपयोगकर्ता को हेरफेर करना चाहता हूं।
एलिनिनलेंडन

जवाबों:


136

मेरा मानना ​​है कि ऐसा करने का सही तरीका है (लारवेल 5.x में) अपने कस्टम फील्ड्स को प्रॉपर्टीज में जोड़ना है।

स्रोत कोड टिप्पणियों से, हम देख सकते हैं कि विशेषताएँ कस्टम मापदंडों के लिए उपयोग की जाती हैं:

 /**
 * Custom parameters.
 *
 * @var \Symfony\Component\HttpFoundation\ParameterBag
 *
 * @api
 */
public $attributes;

तो आप इसे इस प्रकार लागू करेंगे;

$request->attributes->add(['myAttribute' => 'myValue']);

तब आप कॉल करके विशेषता पुनः प्राप्त कर सकते हैं:

\Request::get('myAttribute');

या लार्वा 5.5 + में अनुरोध वस्तु से

 $request->get('myAttribute');

1
फिर आप नियंत्रक को प्राप्त करने वाले गुणों का उपयोग कैसे करते हैं?
user985366


8
$ myAttribute = \ Request :: get ('myAttribute');
शॉन सी।

4
वाह, यह समाधान बहुत साफ दिखता है!
schellingerht

3
आप $request->request->add(['myAttribute' => 'myValue']);जादू पाने वाले शॉर्टहैंड का उपयोग करने में सक्षम होने के लिए भी उपयोग कर सकते हैं$request->myAttribute
jonan.pineda

29

कस्टम अनुरोध मापदंडों के बजाय, आप उलटा-के-नियंत्रण पैटर्न का पालन कर सकते हैं और निर्भरता इंजेक्शन का उपयोग कर सकते हैं।

अपने मिडलवेयर में, अपना Pageउदाहरण दर्ज करें :

app()->instance(Page::class, $page);

फिर घोषित करें कि आपके नियंत्रक को एक Pageउदाहरण की आवश्यकता है :

class PagesController 
{
    protected $page;

    function __construct(Page $page) 
    {
        $this->page = $page;
    }
}

लारवेल स्वचालित रूप से निर्भरता को हल करेगा और आपके नियंत्रक को उस Pageउदाहरण के साथ त्वरित करेगा जिसे आप अपने मिडलवेयर में बांधते हैं।


1
यह वास्तव में अच्छा विचार है, मैंने आगे बढ़कर एक सेवा प्रदाता बनाया और फिर एक सेवा कंटेनर पंजीकृत किया। इस तरह जब कुछ विशेषताओं की आवश्यकता होती है, तो मैं सिर्फ निर्भरता को इंजेक्ट करूंगा। बहुत साफ और पारदर्शी। धन्यवाद!
एरियन अकोस्टा

1
@ArianAcosta कृपया, क्या आप अपने तरीके से उत्तर विस्तृत कर सकते हैं? मेरा मतलब है, निर्भरता इंजेक्शन का उपयोग कैसे करें और यह मिडलवेयर के साथ कैसे जुड़ा हुआ है।
JCarlosR

4
@ जेकार्लोस ज़रूर! यह विचार एक कस्टम सर्विस कंटेनर क्लास होगा जो आंतरिक गुणों के रूप में डेटा को रखता है जिसे आपको मिडलवेयर और कंट्रोलर के बीच से गुजरना पड़ता है। यदि आप उस सेवा कंटेनर को एक सिंगलटन के रूप में $ इस के साथ रजिस्टर करते हैं-> ऐप-> सिंगलटन (...) तो, यह हमेशा एक ही उदाहरण होगा जब भी आप इसे इंजेक्ट करेंगे। इसलिए, अनिवार्य रूप से आप पहले इसे मिडलवेयर में इंजेक्ट करेंगे (केवल तर्क के रूप में इसकी आवश्यकता होती है), फिर इसके अंदर डेटा डालें, और अंत में इसे कंट्रोलर में आवश्यक करें जहां आप डेटा एक्सेस कर सकते हैं। देखिए laravel.com/docs/5.4/container गुड लक
एरियन

2
यह एक महान जवाब है ... साफ! :)
पिएत्रो

5
टिप्पणी: __constructor में यह काम नहीं करता है, क्योंकि नियंत्रक के निर्माण के बाद मिडलवेयर लोड किया जाता है। लेकिन आप नियंत्रक की किसी भी कार्रवाई में DI का उपयोग कर सकते हैं।
सेरही टोपोल्त्स्की

18

लारवेल में = 5 आप $request->mergeमिडलवेयर में उपयोग कर सकते हैं :

public function handle($request, Closure $next)
{

    $request->merge(array("myVar" => "1234"));

    return $next($request);
}

और नियंत्रक में:

public function index(Request $request)
{

    $myVar = $request->instance()->query('myVar');
    ...
}

11
आप उपयोग करने के Request::instance()बजाय सांख्यिकीय रूप से क्यों एक्सेस करेंगे $request?
जजोक

17

लारवेल 5.7

// in Middleware register instance
app()->instance('myObj', $myObj);

तथा

// to get in controller just use the resolve helper
$myObj = resolve('myObj');

7

जैसा कि ऊपर दिए गए टिप्पणियों में से एक में बताया गया है कि लार्वा 5.3.x

$request->attributes->add(['key => 'value'] ); 

काम नहीं करता है। लेकिन इस तरह के वेरिएबल को मिडिलवेयर काम में लगाना

$request->attributes->set('key', 'value');

मैं अपने नियंत्रक में इसका उपयोग करके डेटा प्राप्त कर सकता हूं

$request->get('key');

6

मुझे यकीन है कि अगर किसी मिडलवेयर से कंट्रोलर तक डेटा पास करना संभव था तो यह लारवेल डॉक्यूमेंटेशन में होगा।

इस पर एक नज़र डालें और यह मदद कर सकता है।

संक्षेप में, आप अपने डेटा को अनुरोध वस्तु पर वापस रख सकते हैं जिसे मिडलवेयर को पास किया जा रहा है। लारवेल प्रमाणीकरण मुखौटा भी ऐसा करता है।

तो, आपके मिडलवेयर में, आप कर सकते हैं:

$request->myAttribute = "myValue";

धन्यवाद @ नोर्मन - एक अच्छा समाधान है और मुझे नहीं पता था कि आप इसे कर सकते थे ...! मैं सवाल कर रहा था कि क्या मुझे इस बिंदु पर मिडलवेयर का उपयोग करना चाहिए, लेकिन ऐसा लगता है कि मुझे चाहिए। दस्तावेज़ में किसी भी प्रकार का उल्लेख नहीं है। धन्यवाद फिर से
एलेक्स

1
@ एलेक्स हां, मुझे लगता है कि अगर कोड का एक सामान्य टुकड़ा जो प्रत्येक नियंत्रक कार्रवाई में निष्पादित होता है, तो इसे मिडलवेयर के रूप में लागू करना एक बुरा विचार नहीं है।
नोमान उर रहमान

5

यह बहुत ही सरल है:

यहाँ मिडलवेयर कोड है:

public function handle($request, Closure $next)
{

    $request->merge(array("customVar" => "abcde"));

    return $next($request);
}

और यहाँ नियंत्रक कोड है:

$request->customVar;

2

यदि आपकी वेबसाइट में cms पृष्ठ हैं, जो डेटाबेस से प्राप्त किए जा रहे हैं और सभी शीर्षकों और शीर्ष लेख ब्लॉक में लारवल एप्लिकेशन के सभी पृष्ठों पर अपने शीर्षक दिखाना चाहते हैं तो मिडलवेयर का उपयोग करें। नीचे दिए गए कोड को अपने मिडलवेयर में लिखें:

namespace App\Http\Middleware;

use Closure;

use Illuminate\Support\Facades\DB;

public function handle($request, Closure $next)
{    

$data = DB::table('pages')->select('pages.id','pages.title')->where('pages.status', '1')->get();

\Illuminate\Support\Facades\View::share('cms_pages', $data);

return $next($request);

}

फिर अपने हेडर .blade.php और footer.blade.php और cms पृष्ठों के लिंक जोड़ने के लिए कोड के नीचे लिखें:

<a href="{{ url('/') }}">Home</a> | 

@foreach ($cms_pages as $page) 

<a href="{{ url('page/show/'.$page->id) }}">{{ $page->title }}</a> | 

@endforeach

<a href="{{ url('contactus') }}">Contact Us</a>

सभी को बहुत बहुत धन्यवाद और कोड का आनंद लें :)


1

मैं अंग्रेजी नहीं बोलता, इसलिए ... संभव त्रुटियों के लिए क्षमा करें।

आप इसके लिए IoC बाइंडिंग का उपयोग कर सकते हैं। अपने मिडलवेयर में आप $ पेज का उदाहरण बाँधने के लिए ऐसा कर सकते हैं:

\App::instance('mi_page_var', $page);

अपने नियंत्रक में, आप उस उदाहरण को कहते हैं:

$page = \App::make('mi_page_var');

एप्लिकेशन :: उदाहरण वर्ग को फिर से आवृत्ति नहीं करता है, इसके बजाय पहले से बंधे हुए उदाहरण को वापस लौटाता है।


1

मैं अनुरोध-ऑब्जेक्ट के साथ मान जोड़ने में सक्षम था:

$request->attributes->set('key', 'value');

और उन्हें बाद के बिंदु पर वापस लाएं:

$request->attributes->get('key');

क्योंकि यह संभव है laravels अनुरोध फैली symfonys अनुरोध जो विशेषता "है $ विशेषताओं प्रकार के" ParameterBag कि पकड़ करने का इरादा है कस्टम पैरामीटर

मुझे लगता है कि बाद के मिडलवेयर, कंट्रोलर्स या किसी अन्य स्थान पर डेटा पास करने के लिए यह सर्वश्रेष्ठ अभ्यास होना चाहिए जहां अनुरोध-ऑब्जेक्ट तक पहुंचना संभव हो।

लारवेल 5.6 के साथ परीक्षण किया गया , लेकिन शायद अन्य संस्करणों के साथ भी काम कर रहा है।


1

$requestवह सरणी है जिससे हम केवल सरणी में मान और कुंजी जोड़ सकते हैं और $requestनियंत्रक में इस कुंजी के साथ प्राप्त कर सकते हैं ।

$request['id'] = $id;

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.