หลายภาษา

การสนับสนุนหลายภาษาจะใช้ symfony/translation คอมโพเนนต์

การติดตั้ง

composer require symfony/translation

สร้างแพ็คเกจภาษา

webman จะวางแพ็คเกจภาษาที่ resource/translations โดยปริยาย (ถ้ายังไม่มีโปรดสร้างขึ้นมาเอง) หากต้องการเปลี่ยนไดเรกทอรี โปรดตั้งค่าใน config/translation.php
แต่ละภาษา จะตรงกับโฟลเดอร์ย่อยในนั้น การกำหนดค่าสำหรับภาษาจะถูกวางไว้ในไฟล์ messages.php โดยปริยาย ตัวอย่างตามด้านล่าง:

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

ไฟล์ภาษาทั้งหมดจะคืนค่าเป็นอาร์เรย์ ตัวอย่างเช่น:

// resource/translations/en/messages.php

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

การตั้งค่า

config/translation.php

return [
    // ภาษาที่เป็นค่าเริ่มต้น
    'locale' => 'zh_CN',
    // ภาษาสำรอง หากไม่พบการแปลในภาษาปัจจุบัน จะพยายามใช้การแปลจากภาษาสำรอง
    'fallback_locale' => ['zh_CN', 'en'],
    // โฟลเดอร์สำหรับจัดเก็บไฟล์ภาษา
    'path' => base_path() . '/resource/translations',
];

การแปล

การแปลจะใช้เมธอด trans()

สร้างไฟล์ภาษา resource/translations/zh_CN/messages.php ดังนี้:

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

สร้างไฟล์ 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 จะส่งคืน "你好 世界!"

เปลี่ยนภาษาเริ่มต้น

การเปลี่ยนภาษาจะใช้เมธอด 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!"

คุณยังสามารถใช้พารามิเตอร์ที่ 4 ของฟังก์ชัน trans() เพื่อเปลี่ยนภาษาแบบชั่วคราว ตัวอย่างเช่น ตัวอย่างข้างต้นและตัวอย่างนี้เท่ากัน:

<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function get(Request $request)
    {
        // พารามิเตอร์ที่ 4 เปลี่ยนภาษา
        $hello = trans('hello', [], null, 'en'); // hello world!
        return response($hello);
    }
}

ตั้งภาษาสำหรับแต่ละคำขออย่างชัดเจน

การแปลเป็นซิงเกิลตัน ซึ่งหมายความว่าทุกคำขอจะแชร์ตัวอย่างนี้ ถ้าคำขอใดใช้ locale() ตั้งค่าภาษาเริ่มต้น มันจะมีผลต่อคำขอถัดไปทั้งหมดในโพรเซสนี้ ดังนั้นเราควรตั้งค่าภาษาอย่างชัดเจนสำหรับแต่ละคำขอ ตัวอย่างเช่น โดยใช้ middleware ต่อไปนี้

สร้างไฟล์ app/middleware/Lang.php (ถ้าไดเรกทอรีไม่มีโปรดสร้างขึ้นมาเอง) ดังนี้:

<?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 เพิ่ม middleware ทั่วไปดังนี้:

return [
    // middleware ทั่วไป
    '' => [
        // ... ที่นี่ละเลย middleware อื่น ๆ
        app\middleware\Lang::class,
    ]
];

การใช้ตัวแทน

ในบางครั้ง ข้อความหนึ่งอาจมีตัวแปรที่ต้องได้รับการแปล เช่น

trans('hello ' . $name);

เมื่อเจอสถานการณ์เช่นนี้ เราจะใช้ตัวแทนในการจัดการ

เปลี่ยน resource/translations/zh_CN/messages.php ดังนี้:

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

ในขณะแปลให้ส่งค่าตัวแทนผ่านพารามิเตอร์ที่สองเข้าไป

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

การจัดการกับจำนวนพหูพจน์

บางภาษาเมื่อจำนวนมีการเปลี่ยนแปลง จะส่งผลต่อรูปประโยค เช่น There is %count% apple เมื่อ %count% เท่ากับ 1 รูปประโยคจะถูกต้อง แต่เมื่อตัวเลขมากกว่า 1 จะไม่ถูกต้อง

เมื่อพบสถานการณ์เช่นนี้ เราจะใช้ ท่อ (|) เพื่อระบุตัวเลือกพหูพจน์

เพิ่ม apple_count ในไฟล์ภาษา resource/translations/en/messages.php ดังนี้:

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

เรายังสามารถกำหนดช่วงตัวเลขเพื่อสร้างกฎพหูพจน์ที่ซับซ้อนยิ่งขึ้น:

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

ระบุไฟล์ภาษา

ชื่อไฟล์ภาษาจะเป็น messages.php โดยปริยาย อย่างไรก็ตาม คุณสามารถสร้างไฟล์ภาษาอื่นที่มีชื่อได้

สร้างไฟล์ภาษา resource/translations/zh_CN/admin.php ดังนี้:

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

โดยใช้พารามิเตอร์ที่ 3 ของ trans() เพื่อระบุไฟล์ภาษา (ละเว้นนามสกุล .php).

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

ข้อมูลเพิ่มเติม

ดูที่ symfony/translation คู่มือ