다국어

다국어는 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!"가 반환됩니다.

trans() 함수의 네 번째 매개변수를 사용하여 임시로 언어를 전환할 수도 있습니다. 예를 들어 위의 예시와 아래 예시는 같습니다:

<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function get(Request $request)
    {
        // 네 번째 매개변수로 언어 전환
        $hello = trans('hello', [], null, 'en'); // hello world!
        return response($hello);
    }
}

각 요청에 대해 명시적으로 언어 설정

translation은 싱글턴입니다. 이는 모든 요청이 이 인스턴스를 공유함을 의미합니다. 만약 어떤 요청이 locale()로 기본 언어를 설정하면, 이후 이 프로세스의 모든 요청에 영향을 미칩니다. 따라서 각 요청에 대해 명시적으로 언어를 설정해야 합니다. 예를 들어, 다음 미들웨어를 사용할 수 있습니다.

파일 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에 전역 미들웨어를 추가합니다:

return [
    // 전역 미들웨어
    '' => [
        // ... 다른 미들웨어 생략
        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보다 클 경우 잘못됩니다.

이런 경우 복수형을 나열하기 위해 파이프(|)를 사용합니다.

언어 파일 resource/translations/en/messages.phpapple_count를 추가합니다:

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' => '你好 管理员!',
];

trans()의 세 번째 매개변수를 통해 언어 파일을 지정할 수 있습니다(.php 접미사를 생략).

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

추가 정보

자세한 내용은 symfony/translation 문서를 참조하세요.