检测语言并重定向到 Symfony 上的子域

发布于 2024-09-07 02:45:09 字数 3035 浏览 2 评论 0原文

我正在使用 Symfony 1.2.7。我的网站采用多种语言,每种语言都位于 en.example.com、es.example.com 等子域中。如果用户进入 example.com,我想将他重定向到他的语言。我还希望支持 staging.example.com 并重定向到 es.staging.example.com 和 en.staging.example.com,以便我可以在部署之前测试所有内容。

我有以下代码,适用于index.php 和frontend_dev.php。我的问题是,你能改进它吗?有更好或更干净的方法吗?谢谢!

require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');

$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'dev', true);
$context = sfContext::createInstance($configuration);

// get the domain parts as an array
$host = array_reverse(explode('.', $_SERVER['HTTP_HOST']));
list($tld, $domain, $subdomain) = $host;

// determine which subdomain we're looking at
$app = ($subdomain == 'staging') ? $subdomain2=$host[3] : $subdomain;

if(empty($app) || $app == 'www')
{
  $browser_languages = $context->getRequest()->getLanguages();

  foreach($browser_languages as $language)
  {
    $allowed_culture = in_array($language, sfConfig::get('app_languagesAvailable'));
    if($allowed_culture)
    {
      $domain = $subdomain ? $subdomain.'.'.$domain : $domain;
      $url = 'http://'.str_replace($domain.'.'.$tld, $language.'.'.$domain.'.'.$tld, $_SERVER['HTTP_HOST']).$_SERVER['REQUEST_URI'];

      $context->getController()->redirect($url);
      break;
    }
  }
}

$context->dispatch();

更新解决方案:自定义过滤器

<?php

class subdomainFilter extends sfFilter
{
    public function execute($filterChain)
    {
        $context = $this->getContext();
        $user = $this->getContext()->getUser();
        $request = $this->getContext()->getRequest();

        // get the domain parts as an array
        $host = array_reverse(explode('.', $request->getHost()));
        list($tld, $domain) = $host;
        $subdomain2 = $host[3];
        $subdomain = $host[2];

        // determine which subdomain we're looking at
        $app = ($host[2] == 'staging') ? $subdomain2 : $subdomain;

        if(empty($app) || $app == 'www')
        {
          // if first time
          if ($this->isFirstCall())
          {
            $browser_languages = $request->getLanguages();
            // set default lang, for API as CURL doesn't set the language
            $lang = sfConfig::get('app_default_culture');

            foreach($browser_languages as $language)
            {
              $allowed_culture = in_array($language, sfConfig::get('app_languagesAvailable'));
              if($allowed_culture)
              {
                $lang = $language;
                break;
              }
            }
          }else {
            // Get user culture
            $lang = $user->getCulture();
          }

          $domain = $subdomain ? $subdomain.'.'.$domain : $domain;
          $url = str_replace($domain.'.'.$tld, $lang.'.'.$domain.'.'.$tld, $request->getURI());
          $context->getController()->redirect($url);
        }

        $filterChain->execute();
    }
}

I'm using Symfony 1.2.7. My web is in several languages, each of one is in a subdomain like en.example.com, es.example.com. If the user enters into example.com, I want to redirect him to his language. I also want to have support staging.example.com and redirect to es.staging.example.com and en.staging.example.com so I can test everything before the deployment.

I have the following code that works both on index.php and frontend_dev.php. My question is, can you improve it? is there a better or cleaner way? Thanks!

require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');

$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'dev', true);
$context = sfContext::createInstance($configuration);

// get the domain parts as an array
$host = array_reverse(explode('.', $_SERVER['HTTP_HOST']));
list($tld, $domain, $subdomain) = $host;

// determine which subdomain we're looking at
$app = ($subdomain == 'staging') ? $subdomain2=$host[3] : $subdomain;

if(empty($app) || $app == 'www')
{
  $browser_languages = $context->getRequest()->getLanguages();

  foreach($browser_languages as $language)
  {
    $allowed_culture = in_array($language, sfConfig::get('app_languagesAvailable'));
    if($allowed_culture)
    {
      $domain = $subdomain ? $subdomain.'.'.$domain : $domain;
      $url = 'http://'.str_replace($domain.'.'.$tld, $language.'.'.$domain.'.'.$tld, $_SERVER['HTTP_HOST']).$_SERVER['REQUEST_URI'];

      $context->getController()->redirect($url);
      break;
    }
  }
}

$context->dispatch();

Update Solution: Custom filter

<?php

class subdomainFilter extends sfFilter
{
    public function execute($filterChain)
    {
        $context = $this->getContext();
        $user = $this->getContext()->getUser();
        $request = $this->getContext()->getRequest();

        // get the domain parts as an array
        $host = array_reverse(explode('.', $request->getHost()));
        list($tld, $domain) = $host;
        $subdomain2 = $host[3];
        $subdomain = $host[2];

        // determine which subdomain we're looking at
        $app = ($host[2] == 'staging') ? $subdomain2 : $subdomain;

        if(empty($app) || $app == 'www')
        {
          // if first time
          if ($this->isFirstCall())
          {
            $browser_languages = $request->getLanguages();
            // set default lang, for API as CURL doesn't set the language
            $lang = sfConfig::get('app_default_culture');

            foreach($browser_languages as $language)
            {
              $allowed_culture = in_array($language, sfConfig::get('app_languagesAvailable'));
              if($allowed_culture)
              {
                $lang = $language;
                break;
              }
            }
          }else {
            // Get user culture
            $lang = $user->getCulture();
          }

          $domain = $subdomain ? $subdomain.'.'.$domain : $domain;
          $url = str_replace($domain.'.'.$tld, $lang.'.'.$domain.'.'.$tld, $request->getURI());
          $context->getController()->redirect($url);
        }

        $filterChain->execute();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

单身情人 2024-09-14 02:45:09

使用 Symfony 的路由系统是解决此类问题的正确解决方案。

看看
http://www.symfony-project.org/jobeet/1_2/教义/zh/05
对于一般路由信息和
http://www.symfony-project.org/blog/2009/03/02/call-the-expert-adding-subdomain-requirements-to-routing-yml
对于高级路由问题。

注意:我强烈建议更新到 sf 1.4,因为 1.2 不再维护。 (http://www.symfony-project.org/tutorial/1_4/en /升级

Using Symfony's routing system is the proper solution for these kind of issues.

Take a look at
http://www.symfony-project.org/jobeet/1_2/Doctrine/en/05
for general routing info and at
http://www.symfony-project.org/blog/2009/03/02/call-the-expert-adding-subdomain-requirements-to-routing-yml
for advanced routing issues.

Note: I strongly suggest updating to sf 1.4 because 1.2 isn't maintained anymore. (http://www.symfony-project.org/tutorial/1_4/en/upgrade)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文