对于多语言网站,我们可以用 en.fecshop.com,fr.fecshop.com,es.fecshop.com, 这种子域名的方式表现做多语言
也可以用 www.fecshop.com , www.fecshop.com/fr , www.fecshop.com/es , 这种方式做多语言
yii2对第一种支持还是不错,对于第二种支持不好,我们搞一种自己的方式来支持这种。
1.在app/web/下面新建文件夹
app/web/fr
app/web/es
在上面的文件夹下面新建index.php文件,assets文件夹设置可写。
/app/web/fr/index.php
1.nginx设置:
在nginx的server配置中加入:
location /fr/ {
index index.php;
if (!-e $request_filename){
rewrite . /fr/index.php last;
}
}
2.入口/app/web/fr/index.php文件开始加入:
$secure = 0;
$http = $secure ? 'https' : 'http';
$homeUrl = $http.'://'.$_SERVER['HTTP_HOST'].rtrim(dirname($_SERVER['SCRIPT_NAME']), '\\/');
$application = new yii\web\Application($config);
的上面加入:
$config['homeUrl'] = $homeUrl;
加完之后的样子:
<?php
//$secure = isset($_SERVER['HTTPS']) && (strcasecmp($_SERVER['HTTPS'], 'on') === 0 || $_SERVER['HTTPS'] == 1) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') === 0;
$secure = 0;
$http = $secure ? 'https' : 'http';
$homeUrl = $http.'://'.$_SERVER['HTTP_HOST'].rtrim(dirname($_SERVER['SCRIPT_NAME']), '\\/');
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require(__DIR__ . '/../../../vendor/autoload.php');
require(__DIR__ . '/../../../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../../../common/config/bootstrap.php');
require(__DIR__ . '/../../config/bootstrap.php');
$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../../common/config/main.php'),
require(__DIR__ . '/../../../common/config/main-local.php'),
require(__DIR__ . '/../../config/main.php'),
require(__DIR__ . '/../../config/main-local.php')
);
$config['homeUrl'] = $homeUrl;
$application = new yii\web\Application($config);
$application->run();
3.添加store组件:
'store' => [
'class' => 'fecshop\services\Store',
'stores' => [
'fecshop.appadmin.fancyecommerce.com/fr' => [
'language' => 'fr',
'themePackage' => 'default',
'theme' => 'default',
'currency' => 'USD',
],
'fecshop.appadmin.fancyecommerce.com/es' => [
'language' => 'es',
'themePackage' => 'default',
'theme' => 'default',
'currency' => 'USD',
],
'fecshop.appadmin.fancyecommerce.com' => [
'language' => 'en',
'themePackage' => 'default',
'theme' => 'default',
'currency' => 'USD',
],
],
'languages' => [
//'en','fr','it','de','es','nl','pt','ru',
],
],
组件:
<?php
/**
* FecShop file.
*
* @link http://www.fecshop.com/
* @copyright Copyright (c) 2016 FecShop Software LLC
* @license http://www.fecshop.com/license/
*/
namespace fecshop\services;
use Yii;
use yii\base\InvalidValueException;
use yii\base\InvalidConfigException;
use yii\base\BootstrapInterface;
/**
* @author Terry Zhao <2358269014@qq.com>
* @since 1.0
*/
class Store extends Service implements BootstrapInterface
{
/**
* init by config file.
* all stores config . include : domain,language,theme,themePackage
*/
public $stores;
/**
* init by config file.
* all store Language.
*/
public $languages;
/**
* current store language
*/
public $currentLanguage = 'en';
/**
* current store theme package
*/
public $currentThemePackage = 'default';
/**
* current store theme
*/
public $currentTheme = 'default';
/**
* current store name , this property will init value with domain.
*/
public $currentStore;
/**
* Bootstrap:init website, class property $currentLanguage ,$currentTheme and $currentStore.
* if you not config this ,default class property will be set.
* if current domain is not config , InvalidValueException will be throw.
* class property $currentStore will be set value $domain.
*/
public function bootstrap($app){
$host = explode('://' ,$app->getHomeUrl());
$stores = $this->stores;
$init_compelte = 0;
if(is_array($stores) && !empty($stores)){
foreach($stores as $domain => $lang){
if($host[1] == $domain){
Yii::$app->store->currentStore = $domain;
if(isset($lang['language']) && !empty($lang['language'])){
Yii::$app->store->currentLanguage = $lang['language'];
}
if(isset($lang['theme']) && !empty($lang['theme'])){
Yii::$app->store->currentTheme = $lang['theme'];
}
if(isset($lang['themePackage']) && !empty($lang['themePackage'])){
Yii::$app->store->currentThemePackage = $lang['themePackage'];
}
/**
* init store currency.
*/
if(isset($lang['currency']) && !empty($lang['currency'])){
$currency = $lang['currency'];
}else{
$currency = '';
}
Yii::$app->page->currency->initCurrency($currency);
/**
* current domian is config is store config.
*/
$init_compelte = 1;
}
}
}
if(!$init_compelte){
throw new InvalidValueException('this domain is not config in store component');
}
}
/**
* if a object or array attribute is a store attribute, you can get current
* language value by this function.
*/
public function getLangVal($attr,$attrName){
return $attr[$this->currentLanguage."_".$attrName];
}
public function getAllLanguage(){
}
}
上面通过相应的域名设置不同的语言,货币,模板等。
4.yii的yii\helpers\Url已经对我们不适合,我们需要自己写一个url的生成:
<?php
namespace fec\helpers;
use Yii;
class CUrl
{
public static $_baseHttpUrl;
public static $_baseHttpsUrl;
# 1.获取首页地址。
public static function getHomeUrl(){
return Yii::$app->getHomeUrl();
//return Yii::$app->getBaseUrl(true);
}
# 2. 获取首页地址。同上
public static function getBaseUrl($isHttps=false){
if($isHttps){
if(!self::$_baseHttpsUrl){
self::$_baseHttpsUrl = str_replace('http','https',self::getHomeUrl());
}
return self::$_baseHttpsUrl;
}else{
if(!self::$_baseHttpUrl){
self::$_baseHttpUrl = str_replace('https','http',self::getHomeUrl());
}
return self::$_baseHttpUrl;
}
}
# 3.立即跳转 和 yii2的跳转还是不同
public static function redirect($url,$isHttps=false){
if($url){
if(substr($url,0,4) != "http"){
$url = self::getUrl($url,[],$isHttps);
}
header("Location: $url");
exit;
}
}
# 4.通过模板name,得到对应文件路径。
# 默认是 domain.com/skin/theme/下面的绝对URL
public static function getSkinUrl($dir = '',$relative_path=false){
$currentTheme = CConfig::getCurrentTheme();
$url = '';
if(!$relative_path){
$url = self::getHomeUrl(). DIRECTORY_SEPARATOR;
}
return $url.'skin'.DIRECTORY_SEPARATOR
.$currentTheme.DIRECTORY_SEPARATOR
.$dir;
}
#5. 通过url path 和参数 得到当前网站下的完整url路径。
public static function getUrl($url_path,$params=array(),$isHttps=false){
$url_path = trim($url_path,DIRECTORY_SEPARATOR);
$url = self::getBaseUrl($isHttps). DIRECTORY_SEPARATOR .$url_path;
$str = "";
if(!empty($params) && is_array($params)){
$str .= "?";
foreach($params as $k=>$v){
$str .= $k."=".$v."&";
}
$str = substr($str,0,strlen($str)-1);
}
return $url.$str;
}
# 6.得到当前的完整url
public static function getCurrentUrl(){
//$s = self::getHomeUrl();
//return $s.$_SERVER["REQUEST_URI"];
return \yii\helpers\Url::current();
}
# 7.得到当前的完整url no param
public static function getCurrentUrlNoParam(){
$url = self::getCurrentUrl();
if(strstr($url,"#")){
$url = substr($url,0,strpos($url,"#"));
}
if(strstr($url,"?")){
$url = substr($url,0,strpos($url,"?"));
}
return $url;
}
# 8、得到url key ,譬如 http://www.x.com/ss/dd/aa?aaaa=ddddd 返回 /ss/dd/aa
public static function getUrlKey(){
return Yii::$app->request->getPathInfo();
}
# 9.得到url ,譬如 http://www.x.com/ss/dd/aa?aaaa=ddddd 返回 /ss/dd/aa?aaaa=ddddd
public static function getUrlKeyWithParam(){
return Yii::$app->getRequest()->url;
}
}
得到url:
CUrl::getUrl('/x/x/x',['p'=>'2]);
#将生成
http://fecshop.appadmin.fancyecommerce.com/fr/x/x/x?p=2
CUrl::getUrl('/x/x/x',['p'=>'2],rue);
#将生成
https://fecshop.appadmin.fancyecommerce.com/fr/x/x/x?p=2
OK,到这里就完成整个过程了。