2013-03-31 9 views
5

मैं वर्तमान में एक बहुभाषी वेबसाइट विकसित कर रहा हूं। बहुभाषी भाग के लिए मैं अनुवादक/poedit का उपयोग करें। मैं सत्र में चयनित भाषा को स्टोर करता हूं। यह बढ़िया काम करता है।ज़ेंड फ्रेमवर्क 2 मॉडलों के लिए गुजरने वाले चर

Module.php: एक नियंत्रक में भाषा की स्थापना के लिए

public function onBootstrap(MvcEvent $e) 
{ 
    // ... 

    $session = new Container('base'); 

    if ($session->language !== NULL) { 
     $e->getApplication()->getServiceManager()->get('translator')->setLocale($session->language); 
    } 
} 

कार्रवाई:

public function setLanguageAction() 
{ 
    $language = $this->params()->fromRoute('language'); 

    if (isset($this->languages[$language])) { 

     $session = new Container('base'); 

     if ($language == 'en') { 
      $session->language = NULL; 
     } else { 
      $session->language = $language; 
     } 
    } 

    return $this->redirect()->toRoute('home'); 
} 

module.config.php डिफ़ॉल्ट स्थान में एन को तैयार है।

जैसा कि मैंने कहा कि सबकुछ ठीक काम करता है, एक चीज़ को छोड़कर।

मैं डीबी में कुछ भाषा निर्भर डेटा भी स्टोर करता हूं, इसलिए मेरे मॉडल में मुझे यह जानने की ज़रूरत है कि वर्तमान भाषा क्या है। मॉडल में अन्य उद्देश्यों के लिए वर्तमान भाषा की भी आवश्यकता है।

$session = new Container('base'); 

if ($session->language !== NULL) { 
    $this->language = $session->language; 
} else { 
    $this->language = 'default'; 
} 

मुझे लगता है कि यह सबसे अच्छा समाधान नहीं है:

तो मैं हर मॉडल के निर्माण समारोह में यह कोड शामिल। मेरे पास हमेशा इस कोड को शामिल करने के लिए बहुत अधिक मॉडल हैं।

मैं अगर वहाँ Module.php/getServiceConfig समारोह से उदाहरण के लिए अपने मॉडल के सभी के लिए स्वचालित रूप से एक $ भाषा चर पारित करने के लिए एक समाधान है जानना चाहूंगा:

public function getServiceConfig() 
{   
    $session = new Container('base'); 

    return array(
     'factories' => array(
      'Application\Model\SomeThing' => function($sm) { 
       $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter'); 
       $c = new SomeThing($dbAdapter); 
       $c->language = $session->language; 
       return $c; 
      } 
     ) 
    ); 
} 

बेशक यह काम नहीं कर रहा, लेकिन ऐसा कुछ ऐसा करने में सक्षम होना बहुत अच्छा होगा, या एक सामान्य समाधान, जहां फैक्टरी सरणी में प्रत्येक मॉडल की भाषा चर के लिए वर्तमान भाषा का मान असाइन करना आवश्यक नहीं है (उदाहरण के लिए एक सामान्य बूटस्ट्रैप मॉडल, जहां एक ही स्थान पर सभी मॉडलों के लिए यह असाइनमेंट किया जा सकता है)।

क्या मेरी समस्या का समाधान है?

आपकी मदद के लिए धन्यवाद!

एम

उत्तर

4

आप अपने सभी मॉडलों के में भाषा इंजेक्षन नहीं करना चाहते हैं, तो मैं कम से कम एक अन्य तरह की मेरे सिर के ऊपर से सोच सकते हैं।

आप प्रारंभकर्ता का उपयोग कर सकते हैं। एक प्रारंभकर्ता मूल रूप से आपको सेवा प्रबंधक के माध्यम से प्राप्त सेवाओं पर प्रारंभिक कार्य करने की अनुमति देता है। इस प्रकार, इस दृष्टिकोण का उपयोग करने के लिए, आपको सेवा प्रबंधक के माध्यम से अपने मॉडल (कम से कम उन लोगों को जो भाषा की आवश्यकता है) लेना होगा। यदि आपको किसी भी निर्भरता को इंजेक्ट करने की आवश्यकता है तो उन्हें इनवोकैबल्स या शायद कारखानों के रूप में जोड़ने जितना आसान है। initializers के बारे में अधिक जानकारी के लिए आप article I wrote about the service manager पढ़ सकते हैं (initializers के बारे में अनुभाग तक नीचे स्क्रॉल)।

तो, आप क्या कर सकते हैं अपने मॉडल एक इंटरफ़ेस को लागू करता है, उदा है LanguageAwareInterface

namespace User\Model; 

interface LanguageAwareInterface { 
    /** 
    * Gets the language 
    * 
    * @return string 
    */ 
    public function getLanguage(); 

    /** 
    * Sets the language 
    * 
    * @param string $language 
    */ 
    public function setLanguage($language); 
} 

फिर आप अपने मॉडल में निम्नलिखित की तरह कर सकते हैं।

namespace User\Model; 

class MyModel implements \User\Model\LanguageAwareInterface { 
    /** 
    * @var string $language The current language 
    */ 
    protected $language; 

    /** 
    * Gets the language 
    * 
    * @return string 
    */ 
    public function getLanguage() { 
     return $this->language; 
    } 

    /** 
    * Sets the language 
    * 
    * @param string $language 
    */ 
    public function setLanguage($language) { 
     $this->language = $language; 
    } 
} 

अगर आप चाहें तो आप भी एक सार बेस मॉडल श्रेणी से ऊपर कोड है कि कर सकता है, या शायद एक सरल विशेषता बारे में यदि आप एक वर्ग का विस्तार से बचना चाहते हैं।फिर आपके मॉडल प्रत्येक बेस क्लास को बढ़ा सकते हैं, लेकिन यह निर्भर करता है कि आपके मॉडल में से कितने मॉडल को वर्तमान भाषा के साथ काम करने की ज़रूरत है।

अब प्रारंभकर्ता के लिए। मेरे आलेख में मेरे पास विधि कॉल के साथ इसे जोड़ने का एक उदाहरण है, लेकिन संभावना है कि आप इसे अपनी कॉन्फ़िगरेशन फ़ाइल में करना चाहेंगे (शायद Application मॉड्यूल में यदि आप ज़ेंड कंकाल एप्लिकेशन का उपयोग कर रहे हैं)। आप या तो getServiceConfig() विधि में मॉड्यूल के Module कक्षा से एक सरणी (या कॉन्फ़िगरेशन फ़ाइल पर इंगित करें) को वापस कर सकते हैं, या आप service_manager कुंजी के तहत इसे YourModule/config/module.config.php फ़ाइल में जोड़ सकते हैं। आधिकारिक दस्तावेज इस का कोई उदाहरण नहीं देता है; वास्तव में, प्रारंभकर्ता ही एकमात्र चीज गायब हैं। हालांकि, यह काम करना चाहिए।

return array(
    /* Other configuration here */ 

    'service_manager' => array(
     'initializers' => array(
      'language' => function($service, $sm) { 
       // $service is the service that is being fetched from the service manager 
       // $sm is the service manager instance 
       if ($service instanceof \User\Model\LanguageAwareInterface) { 
        $session = new \Zend\Session\Container('base'); 

        if ($session->language === null) { 
         // Fetch default language from configuration 
         $config = $sm->get('Config'); 

         $session->language = $config['translator']['locale']; 
        } 

        $service->setLanguage($session->language); 
       } 
      }, 
     ), 
    ), 
); 

ऊपर प्रारंभकर्ता चेकों हर वस्तु है कि सेवा प्रबंधक से लाई गई अगर यह इंटरफ़ेस हम ऊपर बनाया लागू करता है देखने के लिए है। यदि ऐसा होता है, तो भाषा इंजेक्शन दी जा सकती है। मेरे उदाहरण में, मैं यह देखने के लिए जांच करता हूं कि यह सत्र में सेट है या नहीं, और इसे कॉन्फ़िगरेशन से प्राप्त करें। आपको अपनी सटीक जरूरतों के आधार पर तर्क को ट्विक करना पड़ सकता है। ध्यान दें कि प्रारंभकर्ता को प्रत्येक चलाया जाएगा जब आप सेवा प्रबंधक से ऑब्जेक्ट प्राप्त करेंगे, और इस प्रकार यह थोड़ा ओवरहेड जोड़ देगा। हालांकि, यह महत्वपूर्ण नहीं है क्योंकि जब हम इंटरफ़ेस को कार्यान्वित नहीं करते हैं तो हम केवल एक साधारण प्रकार की जांच कर रहे हैं। साथ ही, सेवाओं को डिफ़ॉल्ट रूप से साझा किया जाता है, जिसका अर्थ है कि एक सेवा केवल एक बार तत्काल हो जाएगी; उसी सेवा के बाद के अनुरोधों को फिर पहले तत्काल पुन: उपयोग किया जाएगा। यह ओवरहेड को और भी सीमित करने में मदद करता है।

0

मैं कल्पना कर सकते हैं कि आप पहले जो कुछ मॉड्यूल आपको इतना है कि यह विश्व स्तर पर उपलब्ध है की इच्छा के Module.php में सेवा प्रबंधक में अपने सत्र मॉडल रजिस्टर सकता है, और इस सेवा के किसी भी समय आप सत्र में पहुंचने की आवश्यकता का उपयोग करें।

public function getServiceConfig() 
{   
    return array(
     'factories' => array(
      'AppSession' => function($sm) { 
        $session = new \Path\To\Session(); 
        $session->doSomething(); 
        return $session; 
      } 
     ) 
    ); 
} 

जब आप सेवा प्रबंधक में अपने आवेदन के दौरान अपने विभिन्न मॉडल पंजीकृत करते हैं, तो अपनी सत्र सेवा इंजेक्ट करें।

public function getServiceConfig() 
{   
    return array(
     'factories' => array(
      'Application\Model\SomeThing' => function($sm) { 
       $c = new SomeThing(); 
       // You will have to create the set and get functions. 
       $c->setDbAdapterService($sm->get('Zend\Db\Adapter\Adapter')); 
       $c->setSessionService($sm->get('AppSession')); 
       return $c; 
      } 
     ) 
    ); 
} 

और अपने नियंत्रक पर भी, यह शुरू से ही सत्र सुई ताकि सत्र के लिए तैयार है और आप के लिए इंतज़ार कर रहा है और अधिक समझ कर सकता है।

अपने module.config.php में ...

return array(
    'controllers' => array(
     'factories' => array(
      'Application\Controller\Something' => function ($sm) { 
       $locator = $sm->getServiceLocator(); 
       $c = new Application\Controller\SomethingController(); 
       $c->setSessionService($locator->get('AppSession')); 
       return $c; 
      }, 
     ), 
    ), 
    'router' => array(
     'routes' => array(
      'myroute' => array(
       'type' => 'Zend\Mvc\Router\Http\Segment', 
       'options' => array(
        'route' => '[/:action]', 
        'defaults' => array(
         'controller' => 'Application\Controller\Something', 
         'action'  => 'index', 
        ), 
       ), 
      ), 
     ), 
    ), 
); 
संबंधित मुद्दे