yii2 在域名后面加一个路径作为首页

对于多语言网站,我们可以用 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,到这里就完成整个过程了。

 

 

 

 

 

 

《yii2 在域名后面加一个路径作为首页》有2个想法

  1. nginx 配置可以这么改

    if ( $request_filename ~* \/(cn|en|tw)\/ ) {
    set $webroot $1;
    }

    location / {
    try_files $uri $uri/ /$webroot/index.php?$args;
    }

发表评论

电子邮件地址不会被公开。 必填项已用*标注