Đa ngôn ngữ

Đa ngôn ngữ sử dụng thành phần symfony/translation.

Cài đặt

composer require symfony/translation

Tạo gói ngôn ngữ

webman mặc định sẽ đặt gói ngôn ngữ trong thư mục resource/translations (nếu không có, vui lòng tự tạo), nếu cần thay đổi thư mục, hãy thiết lập trong config/translation.php. Mỗi ngôn ngữ tương ứng với một thư mục con trong đó, định nghĩa ngôn ngữ mặc định được đặt trong messages.php. Ví dụ như sau:

resource/
└── translations
    ├── en
    │   └── messages.php
    └── zh_CN
        └── messages.php

Tất cả các file ngôn ngữ đều trả về một mảng như sau:

// resource/translations/en/messages.php

return [
    'hello' => 'Hello webman',
];

Cấu hình

config/translation.php

return [
    // Ngôn ngữ mặc định
    'locale' => 'zh_CN',
    // Ngôn ngữ dự phòng, khi không tìm thấy bản dịch trong ngôn ngữ hiện tại thì sẽ thử sử dụng bản dịch trong ngôn ngữ dự phòng
    'fallback_locale' => ['zh_CN', 'en'],
    // Thư mục chứa các file ngôn ngữ
    'path' => base_path() . '/resource/translations',
];

Dịch

Dịch sử dụng phương thức trans().

Tạo file ngôn ngữ resource/translations/zh_CN/messages.php như sau:

return [
    'hello' => '你好 世界!',
];

Tạo file app/controller/UserController.php

<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function get(Request $request)
    {
        $hello = trans('hello'); // 你好 世界!
        return response($hello);
    }
}

Truy cập http://127.0.0.1:8787/user/get sẽ trả về "你好 世界!"

Thay đổi ngôn ngữ mặc định

Chuyển đổi ngôn ngữ sử dụng phương thức locale().

Thêm file ngôn ngữ resource/translations/en/messages.php như sau:

return [
    'hello' => 'hello world!',
];
<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function get(Request $request)
    {
        // Chuyển đổi ngôn ngữ
        locale('en');
        $hello = trans('hello'); // hello world!
        return response($hello);
    }
}

Truy cập http://127.0.0.1:8787/user/get sẽ trả về "hello world!"

Bạn cũng có thể sử dụng tham số thứ 4 của hàm trans() để tạm thời chuyển đổi ngôn ngữ, ví dụ như ví dụ trên và ví dụ dưới đây là tương đương:

<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function get(Request $request)
    {
        // Tham số thứ 4 chuyển đổi ngôn ngữ
        $hello = trans('hello', [], null, 'en'); // hello world!
        return response($hello);
    }
}

Thiết lập ngôn ngữ rõ ràng cho mỗi yêu cầu

translation là một singleton, điều này có nghĩa là tất cả các yêu cầu chia sẻ một instance này, nếu một yêu cầu sử dụng locale() để thiết lập ngôn ngữ mặc định, thì nó sẽ ảnh hưởng đến tất cả các yêu cầu tiếp theo trong quá trình này. Vì vậy, chúng ta nên thiết lập ngôn ngữ rõ ràng cho mỗi yêu cầu. Ví dụ sử dụng middleware sau

Tạo file app/middleware/Lang.php (nếu thư mục không tồn tại vui lòng tự tạo) như sau:

<?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);
    }
}

Trong config/middleware.php thêm middleware toàn cục như sau:

return [
    // Middleware toàn cục
    '' => [
        // ... Ở đây bỏ qua các middleware khác
        app\middleware\Lang::class,
    ]
];

Sử dụng biến thay thế

Đôi khi, một thông điệp chứa các biến cần được dịch, ví dụ:

trans('hello ' . $name);

Gặp trường hợp này, chúng ta sử dụng biến thay thế để xử lý.

Thay đổi resource/translations/zh_CN/messages.php như sau:

return [
    'hello' => '你好 %name%!',
];

Khi dịch, hãy truyền dữ liệu thông qua tham số thứ hai để ánh xạ các giá trị của biến thay thế

trans('hello', ['%name%' => 'webman']); // 你好 webman!

Xử lý số nhiều

Một số ngôn ngữ có thể trình bày các câu khác nhau tùy vào số lượng, ví dụ There is %count% apple, khi %count% bằng 1 thì câu đúng, khi lớn hơn 1 thì sai.

Gặp trường hợp này, chúng ta sử dụng dấu phân cách (|) để liệt kê các hình thức số nhiều.

Trong file ngôn ngữ resource/translations/en/messages.php thêm apple_count như sau:

return [
    // ...
    'apple_count' => 'There is one apple|There are %count% apples',
];
trans('apple_count', ['%count%' => 10]); // There are 10 apples

Chúng ta thậm chí có thể xác định phạm vi số, tạo ra các quy tắc số nhiều phức tạp hơn:

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

Chỉ định file ngôn ngữ

Tên file ngôn ngữ mặc định là messages.php, thực tế bạn có thể tạo ra những file ngôn ngữ với tên khác.

Tạo file ngôn ngữ resource/translations/zh_CN/admin.php như sau:

return [
    'hello_admin' => '你好 管理员!',
];

Thông qua tham số thứ 3 của trans() để chỉ định file ngôn ngữ (bỏ qua hậu tố .php).

trans('hello', [], 'admin', 'zh_CN'); // 你好 管理员!

Thông tin thêm

Tham khảo tài liệu symfony/translation