2015-08-08 67 views
0

我有一个Symfony2应用程序,具有多个语言环境,每个域都有自己的域名(意思是语言环境没有前缀或附加在域后面),如“shoes.com”和“schue.de ”。Symfony2中基于语言环境的参数值

要执行此操作,我正在使用jms_i18n_routing捆绑包,该捆绑包负责设置正确的区域设置。

当我想要集成例如Facebook登录hwi_ouath bundle,,我必须在我的config.yml中设置“应用程序ID”和“应用程序秘密”,但这些应用程序也是特定于语言环境的现在在Facebook上你只能创建一个重定向URL),所以我应该在某处更改参数值,但在容器编译时,我无法访问Request对象,检查语言环境,之后我无法更改参数值。

任何想法如何解决这个问题?

+0

显然,你需要解决的一些其他的方式,因为一个容器被编译后不能更改参数(假设这是一个不可改变的生产容器)。 – zerkms

+0

在编译时真的没有办法获取请求对象? – ghostika

+0

我不这么认为 - 它还不存在(因为它的建筑物严重依赖于容器) – zerkms

回答

0

你可以用工厂服务来做到这一点。

<service id="facebook.factory" class="Acme\Facebook\Factory"> 
    <argument type="service" id="request_stack"/> 
    <argument>%facebook_credentials%</argument> 
</service> 
<service id="facebook" class="Facebook" 
     factory-service="facebook.factory" factory-method="create"/> 

<!-- use "facebook" where you need it --> 

,打造工厂,这样的事情:

namespace Acme\Facebook; 

class Factory 
{ 
    //... 

    public function __construct($requestStack, $credentials) 
    { 
     $this->requestStack = $requestStack; 
     $this->credentials = $credentials; 
    } 

    public function create() 
    { 
     $r = $requestStack->getCurrentRequest(); 
     // throw if $r is null 
     $c = $this->credentials[$r->getHost()]; 
     return new Facebook($c); 
    } 
} 

只要记住,facebook服务将被创建了一次。假设主机名/区域设置在单个请求中不会改变,这应该是确定的。如果它可以改变,请自行注入工厂,并在需要时致电create。当然,在这种情况下,您可以为每个区域设置保存已创建的Facebook对象并重新使用它们。

不幸的是,您将不得不重新定义服务,因为该包使用一组参数配置服务,这在您的情况下是不可接受的。因此,捆绑集成可能无法正常工作,但您仍然可以使用它提供的所有类。

+0

是的,但它不仅仅是Facebook,我的意思是我还有其他事情我想改变,但我找到了解决方案为了那个原因。 – ghostika

0

在我用这个解决方案的目的,也许有人需要这样的事:

在AppKernel我做了一个服务器变量与当前HTTP主机:

class AppKernel extends Kernel 
{ 
    /** 
    * @inheritdoc 
    */ 
    public function __construct($environment, $debug) 
    { 
     parent::__construct($environment, $debug); 
     if ($hostEnv = $this->getHostEnv()) { 
      $_SERVER['SYMFONY__HOST'] = $hostEnv; 
     } 
    } 
    ... 
    private function getHostEnv() 
    { 
     if (!empty($_SERVER['HTTP_HOST'])) { 
      return $_SERVER['HTTP_HOST']; 
     } 

     return null; 
    } 
    public function registerContainerConfiguration(LoaderInterface $loader) 
    { 
     $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml'); 
     $loader->load(__DIR__.'/config/parameters.php'); 
    } 
} 

随着SYMFONY__%服务器变量你可以自动创建参数。

然后parameter.php

<?php 

require_once('PlasticConfig.php'); 

if (!empty($container)) { 
    $plasticConfig = new PlasticConfig($container); 
    $container = $plasticConfig->load(); 
} 

然后PlasticConfig.php

<?php 

use \Symfony\Component\DependencyInjection\ContainerInterface; 

class PlasticConfig { 

    /** 
    * @var Symfony\Component\DependencyInjection\ContainerInterface 
    */ 
    protected $container; 

    public function __construct(ContainerInterface $container) 
    { 
     $this->container = $container; 
    } 

    public function load() 
    { 
     /** 
     * this was defined in the constructor of AppKernel 
     * at console command there is no HTTP_HOST variable 
     */ 
     if (!$this->container->hasParameter('host')) { 
      return $this->container; 
     } 

     $host = $this->container->getParameter('host'); 
     //Magic can be done here, important is, that you return your container instance here 

     return $this->container; 
    } 
} 

在我parameters.yml我有一些参数,名称host_de,HOST_EN ......我将通过遍历所有的参数,如果我找到与当前主机的匹配,那么我有参数名称的区域设置。之后,我只需要设置parameters.yml的facebook参数,其中我有如下参数:facebook.de.app_id: XYfacebook.en.app_id: ZS

+0

你会为每个主机名分别清除缓存吗?你如何从命令行传递主机名? –

+0

不,缓存对于每个主机都是一样的,因为所有内容都是相同的,只是翻译过的功能相同。 – ghostika

0

config.yml

imports: 
    - { resource: parameters.php } #add this import 

hwi_ouath bundle: 
    # put this in the right place 
    app_id: %facebook.app_id% 
    app_secret: %facebook.secret% 

参数。PHP

<?php 

$lang = 'en'; 

if ('schue.de' === $_SERVER['HTTP_HOST']) { 
    $lang = 'de'; 
} // elseif (... 

$container->setParameter('facebook.app_id', $container->getParameter('facebook.'.$lang.'.app_id')); 
$container->setParameter('facebook.secret', $container->getParameter('facebook.'.$lang.'.secret')); 
+0

最后,我的解决方案也没有奏效,就像prod env一样,容器被倾倒,所以它会很快 – ghostika