ThinkPHP 6.0 实现二级目录多语言功能

前言

ThinkPHP内置了多语言功能,但是它是通过判断URL参数、Cookies、HTTP_ACCEPT_LANGUAGE请求参数来返回语言包的,由于多种语言的URL固定的,在搜索引擎抓取页面时,页面返回哪种语言取决于爬虫所带的请求头,这种方法对SEO有一定的影响,难以全面收录各种语言的版本。例如Google webmaster support的“管理多区域和多语言网站”一文中提及到:

Google 建议对每种语言版本的网页使用不同的网址,而不是使用 Cookie 或浏览器设置来调整网页上的内容语言。

如果您希望根据语言设置来动态更改内容或重新路由用户,则请注意,Google 可能无法找到并抓取您的所有变体。这是因为,Googlebot 抓取工具通常来自美国。另外,该抓取工具在发送 HTTP 请求时并不会在请求标头中设置 Accept-Language。

实现

示例项目可在文章底部下载。

  1. 进入tp6项目目录,首先在config\lang.php设置默认语言允许的语言列表。我设置了允许简体中文、繁体中文以及英文。
  2. 设置config\route.php中的路由配置,打开强制路由url_route_must以及完全匹配route_complete_match以避免设置后可能导致的冲突问题。
  3. 进入app目录,新建lang目录,编写语言包。
//zh_cn.php
<?php
return [
	'lang' => '简体中文'
];
//zh_tw.php
<?php
return [
	'lang' => '繁體中文'
];
//en_us.php
<?php
return [
	'lang' => 'English'
];
  1. 编辑controller\Index.php,设置Index方法,返回上述语言包的lang字段,以便测试时识别当前选择的语言。
  2. 编辑route\app.php路由配置,替换为以下内容。后续添加路由可参照下方Route::get的方法。
    这里没有用路由分组功能,以避免访问根目录(如http://localhost/zh-cn/)时提示路由不正确,但是不加上末尾的斜杠又可匹配的问题(http://localhost/zh-cn)。
use think\facade\Route;
use think\facade\Config;
Route::get('/', 'index/index');
$langs = Config::get('lang.allow_lang_list');
foreach($langs as $lang){
	Route::get($lang . '/', 'index/index');
}
  1. 新建app\middleware目录,增加LoadLangPack.php中间件。
<?php
declare (strict_types = 1);

namespace app\middleware;

use Closure;
use think\App;
use think\Lang;
use think\Request;

class LoadLangPack
{
    public function handle($request, Closure $next, Lang $lang, App $app)
    {
		$path = explode('/', $request->pathinfo());
		if(sizeof($path) > 0){

			if(empty($path[0])){
				$langset = $lang->detect();
				return redirect('/' . $langset . '/');
			}else{
				$langset = $path[0];
			}

			$lang->setLangSet($langset);

            $lang->load([
                $app->getThinkPath() . 'lang' . DIRECTORY_SEPARATOR . $langset . '.php',
            ]);

            $app->LoadLangPack($langset);
		}
        return $next($request);
    }
}
  1. app\middleware.php文件中添加注册中间件。
	return [
		\app\middleware\LoadLangPack::class
	];
  1. 尝试访问。访问根目录时,应也会根据参数自动跳转到对应语言。


  2. 另外,还需要对如url()助手函数等涉及到URL生成的函数进行重写。以url()助手函数为例,打开app\common.php,写入以下代码:
use think\facade\Lang;
use think\facade\Route;
use think\route\Url as UrlBuild;

function url(string $url = '', array $vars = [], $suffix = true, $domain = false): UrlBuild
{
	$lang = Lang::getLangSet();
	return Route::buildUrl('/' . $lang . '/' . $url, $vars)->suffix($suffix)->domain($domain);
}

这样在调用url函数时,会自动加上语言路径。使用时需要把除语言外的路径写完整。

下载

https://github.com/TLingC/thinkphp6.0-multilingual-example

原文:https://tlingc.com/2019/08/implementing-secondary-directory-multilingual-function-in-thinkphp-6-0/

发布了16 篇原创文章 · 获赞 1 · 访问量 4690

猜你喜欢

转载自blog.csdn.net/TLingC/article/details/99430686