多語言
多語言使用的是 symfony/translation 組件。
安裝
composer require symfony/translation
建立語言包
webman默認(rèn)將語言包放在resource/translations
目錄下(如果沒有請自行創(chuàng)建),如需更改目錄,請?jiān)?code>config/translation.php中設(shè)置。
每種語言對應(yīng)其中的一個子文件夾,語言定義默認(rèn)放到messages.php
里。示例如下:
resource/
└── translations
├── en
│?? └── messages.php
└── zh_CN
└── messages.php
所有的語言文件都是返回一個數(shù)組例如:
// resource/translations/en/messages.php
return [
'hello' => 'Hello webman',
];
配置
config/translation.php
return [
// 默認(rèn)語言
'locale' => 'zh_CN',
// 回退語言,當(dāng)前語言中無法找到翻譯時則嘗試使用回退語言中的翻譯
'fallback_locale' => ['zh_CN', 'en'],
// 語言文件存放的文件夾
'path' => base_path() . '/resource/translations',
];
翻譯
翻譯使用trans()
方法。
創(chuàng)建語言文件 resource/translations/zh_CN/messages.php
如下:
return [
'hello' => '你好 世界!',
];
創(chuàng)建文件 app/controller/UserController.php
<?php
namespace app\controller;
use support\Request;
class UserController
{
public function get(Request $request)
{
$hello = trans('hello'); // 你好 世界!
return response($hello);
}
}
訪問 http://127.0.0.1:8787/user/get
將返回 "你好 世界!"
更改默認(rèn)語言
切換語言使用 locale()
方法。
新增語言文件 resource/translations/en/messages.php
如下:
return [
'hello' => 'hello world!',
];
<?php
namespace app\controller;
use support\Request;
class UserController
{
public function get(Request $request)
{
// 切換語言
locale('en');
$hello = trans('hello'); // hello world!
return response($hello);
}
}
訪問 http://127.0.0.1:8787/user/get
將返回 "hello world!"
你也可以使用trans()
函數(shù)的第4個參數(shù)來臨時切換語言,例如上面的例子和下面這個是等價的:
<?php
namespace app\controller;
use support\Request;
class UserController
{
public function get(Request $request)
{
// 第4個參數(shù)切換語言
$hello = trans('hello', [], null, 'en'); // hello world!
return response($hello);
}
}
為每個請求明確的設(shè)置語言
translation是一個單例,這意味著所有請求共享這個實(shí)例,如果某個請求使用locale()
設(shè)置了默認(rèn)語言,則它會影響這個進(jìn)程的后續(xù)所有請求。所以我們應(yīng)該為每個請求明確的設(shè)置語言。例如使用以下中間件
創(chuàng)建文件app/middleware/Lang.php
(如目錄不存在請自行創(chuàng)建) 如下:
<?php
namespace app\middleware;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
class Lang implements MiddlewareInterface
{
public function process(Request $request, callable $handler) : Response
{
locale(session('lang', 'zh_CN'));
return $handler($request);
}
}
在 config/middleware.php
中添加全局中間件如下:
return [
// 全局中間件
'' => [
// ... 這里省略其它中間件
app\middleware\Lang::class,
]
];
使用占位符
有時,一條信息包含著需要被翻譯的變量,例如
trans('hello ' . $name);
遇到這種情況時我們采用占位符來處理。
更改 resource/translations/zh_CN/messages.php
如下:
return [
'hello' => '你好 %name%!',
];
翻譯的時候?qū)?shù)據(jù)通過第二個參數(shù)將占位符對應(yīng)的值傳遞進(jìn)去
trans('hello', ['%name%' => 'webman']); // 你好 webman!
處理復(fù)數(shù)
有些語言由于事物數(shù)量不同呈現(xiàn)不同的句式,例如There is %count% apple
,當(dāng)%count%
為1時句式正確,當(dāng)大于1時則錯誤。
遇到這種情況時我們采用管道(|
)來列出來復(fù)數(shù)形式。
語言文件 resource/translations/en/messages.php
新增apple_count
如下:
return [
// ...
'apple_count' => 'There is one apple|There are %count% apples',
];
trans('apple_count', ['%count%' => 10]); // There are 10 apples
我們甚至可以指定數(shù)字范圍,創(chuàng)建更加復(fù)雜的復(fù)數(shù)規(guī)則:
return [
// ...
'apple_count' => '{0} There are no apples|{1} There is one apple|]1,19] There are %count% apples|[20,Inf[ There are many apples'
];
trans('apple_count', ['%count%' => 20]); // There are many apples
指定語言文件
語言文件默認(rèn)名字為messages.php
,實(shí)際上你可以創(chuàng)建其它名稱的語言文件。
創(chuàng)建語言文件 resource/translations/zh_CN/admin.php
如下:
return [
'hello_admin' => '你好 管理員!',
];
通過trans()
第三個參數(shù)來指定語言文件(省略.php
后綴)。
trans('hello', [], 'admin', 'zh_CN'); // 你好 管理員!