问题描述
我使用的是 Symfony 1.2.7.我的网站有多种语言,每种语言都在一个子域中,例如 en.example.com、es.example.com.如果用户进入 example.com,我想将他重定向到他的语言.我还希望支持 staging.example.com 并重定向到 es.staging.example.com 和 en.staging.example.com,以便我可以在部署前测试所有内容.
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.
我有以下代码可以在 index.php 和 frontend_dev.php 上运行.我的问题是,你能改进它吗?有更好或更清洁的方法吗?谢谢!
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();
}
}
推荐答案
使用 Symfony 的路由系统是此类问题的正确解决方案.
Using Symfony's routing system is the proper solution for these kind of issues.
看看http://www.symfony-project.org/jobeet/1_2/教义/en/05一般路由信息和在http://www.symfony-project.org/blog/2009/03/02/call-the-expert-adding-subdomain-requirements-to-routing-yml用于高级路由问题.
Take a look athttp://www.symfony-project.org/jobeet/1_2/Doctrine/en/05for general routing info and athttp://www.symfony-project.org/blog/2009/03/02/call-the-expert-adding-subdomain-requirements-to-routing-ymlfor advanced routing issues.
注意:我强烈建议更新到 sf 1.4,因为 1.2 不再维护.(http://www.symfony-project.org/tutorial/1_4/en/升级)
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)
这篇关于检测语言并重定向到 Symfony 上的子域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!