2012-11-12 18 views
15

मेरे पास एक लॉगआउट श्रोता है जहां मैं एक लॉगआउट पुष्टिकरण संदेश दिखाते हुए एक फ्लैश संदेश सेट करना चाहता हूं।सिम्फनी 2 - नियंत्रक के बाहर एक फ्लैश संदेश सेट करना

namespace Acme\MyBundle\Security\Listeners; 

use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface; 
use Symfony\Component\Security\Core\SecurityContext; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\RedirectResponse; 

class LogoutListener implements LogoutSuccessHandlerInterface 
{ 
    private $security; 

    public function __construct(SecurityContext $security) 
    { 
    $this->security = $security; 
    } 

    public function onLogoutSuccess(Request $request) 
    { 
    $request->get('session')->getFlashBag()->add('notice', 'You have been successfully been logged out.'); 

    $response = new RedirectResponse('login'); 
    return $response; 
    } 
} 

यहाँ मेरी services.yml है (जैसा कि इस से संबंधित है):

logout_listener: 
    class: ACME\MyBundle\Security\Listeners\LogoutListener 
    arguments: [@security.context] 

यह एक त्रुटि पैदा कर रहा है:

Fatal error: Call to a member function getFlashBag() on a non-object 

मैं इस में एक flashBag संदेश सेट करूँ संदर्भ?

इसके अलावा, राउटर तक पहुंच कैसे प्राप्त करें ताकि मैं हार्ड-कोडित यूआरएल में गुजरने के बजाय यूआरएल ($-- राउटर-> जेनरेट ('लॉगिन') के माध्यम से उत्पन्न कर सकूं?

संकल्प नोट

काम करने के लिए, आप बताना होगा अपने security.yml config लॉग आउट करने पर सत्र रद्द करना नहीं फ़्लैश प्राप्त करने के लिए; अन्यथा, सत्र नष्ट हो जाएगा और आपका फ्लैश कभी प्रकट नहीं होगा।

logout: 
    path: /logout 
     success_handler: logout_listener 
     invalidate_session: false 

उत्तर

21

आप LogoutListener में सत्र और रूटर के लिए सेवाएं इंजेक्षन और इन कार्यों को करने के लिए उन्हें इस्तेमाल करना चाहिए।

logout_listener: 
class: ACME\MyBundle\Security\Listeners\LogoutListener 
arguments: [@security.context, @router, @session] 

फिर अपने वर्ग में आप लिखते हैं:

class LogoutListener implements LogoutSuccessHandlerInterface 
{ 
    private $security; 
    private $router; 
    private $session; 

    public function __construct(SecurityContext $security, Router $router, Session $session) 
    { 
     $this->security = $security; 
     $this->router = $router; 
     $this->session = $session; 
    } 
    [...] 

आप अब सत्र का उपयोग करना चाहते हैं तो आप सिर्फ कह सकते हैं:

$this->session->getFlashBag()->add('notice', 'You have been successfully been logged out.'); 
इस तरह YML में यह करने के लिए है

और उसी तरह आप मार्ग उत्पन्न करने के लिए राउटर सेवा का उपयोग कर सकते हैं।

+0

मैं अपने services.yml वर्धित सेवा कंटेनर वस्तु इंजेक्षन करने के लिए है। मैं सेवाओं को इंजेक्ट कैसे जोड़ूं? मुझे लगता है कि मुझे तर्कों का उपयोग करने की आवश्यकता है, लेकिन मुझे इंजेक्ट करने के लिए वाक्यविन्यास से अनिश्चितता है। – doremi

+0

यह आपको इंजेक्शन सेवाओं के बारे में एक बुनियादी उदाहरण दिखाता है, यहां और पढ़ें: http://symfony.com/doc/current/book/service_container.html –

+1

मेरा सत्र स्पष्ट रूप से नष्ट हो रहा है ताकि फ्लैश मिटा दिया जा सके। मैंने सोचा था कि LogoutSuccess() को कॉल करने से पहले वास्तविक लॉगिंग आउट पहले से ही किया जा चुका था? – doremi

2

आप सत्र वस्तु (और साथ ही किसी अन्य सेवा) सेवा कंटेनर गर्त प्राप्त कर सकते हैं:

$session = $ServiceContainer->get('session'); 
$session->setFlash('notice', 'Message'); 

जिस तरह से आप अलग अलग तरीकों से सेवा कंटेनर के लिए उपयोग कर सकते हैं:

  • से एक नियंत्रक या किसी भी कंटेनर जागरूक वर्ग: बस $-- get ('session') का उपयोग करें;
  • एक सेवा से: आप के रूप में एल्डो ने कहा
+4

यह दृष्टिकोण काम करता है लेकिन यह निर्भरता इंजेक्शन करने का सही तरीका नहीं है। आपको हर जगह कंटेनर इंजेक्शन से बचना चाहिए, जो एक सेवा लोकेटर पैटर्न को लागू करने के लिए कंटेनर का उपयोग कर रहा है, जिसमें दो प्रमुख दोष हैं: आपके सभी वर्ग (यानी आपका मॉडल) सिस्टम के अन्य प्रासंगिक भागों की बजाय सेवा पर निर्भर करेगा (इसे बनाना सिम्फनी के बाहर उन्हें पुन: उपयोग करना असंभव है) और सभी निर्भरताओं को "संकलन-समय" के बजाय रनटाइम पर हल किया जाएगा, यानी जब सिम्फनी बूटस्ट्रैपिंग से पहले कंटेनर को डंप करता है। केवल उन्हीं सेवाओं को इंजेक्ट करें जिन्हें आपको चाहिए, यह सबसे अच्छा अभ्यास है! –

+1

आपके पास एक बिंदु है :) – Xocoatzin

संबंधित मुद्दे