首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

Yii 1.1 國際化 (I18N) 完整實戰:訊息翻譯、日期時間格式化、數字貨幣本地化

     編輯:PHP 綜合知識

Yii 1.1 提供了完整的國際化 (I18N) 支援,涵蓋訊息翻譯、日期時間格式化、數字貨幣本地化三大核心領域。本文系統講解 Yii::t() 訊息翻譯流程、CLocale 區域數據應用、CDateFormatter/CNumberFormatter 格式化實戰,助你構建面向全球用戶的多語言應用。

核心架構概覽

I18N 相關類位於 framework/i18n/:

i18n/
├── CChoiceFormat.php          # 複數形式選擇
├── CDateFormatter.php         # 日期時間格式化
├── CDbMessageSource.php       # 數據庫訊息源
├── CGettextMessageSource.php  # Gettext 訊息源
├── CLocale.php                # 區域數據核心
├── CMessageSource.php         # 訊息源基類
├── CNumberFormatter.php       # 數字貨幣格式化
├── CPhpMessageSource.php      # PHP 陣列訊息源 (默認)
├── data/                      # 內建區域數據 (600+ 文件)
│   ├── en_us.php
│   ├── zh_cn.php
│   └── ...
└── gettext/                   # Gettext 解析器

一、訊息翻譯:Yii::t() 完整流程

1. 標記需翻譯字符串

// 視圖/控制器/模型中
echo Yii::t('app', 'Welcome, {username}!', ['{username}' => $user->name]);
// 類別: app, 訊息: Welcome, {username}!, 參數: 陣列替換

2. 配置訊息源

// protected/config/main.php
'components' => [
    'messages' => [
        'class' => 'CPhpMessageSource',
        'basePath' => 'protected/messages', // 訊息文件根目錄
        // 'cachingDuration' => 3600, // 生產環境啟用緩存
    ],
],

3. 使用 yiic 提取訊息

配置文件 protected/messages/config.php:

return [
    'sourcePath' => dirname(__FILE__) . DIRECTORY_SEPARATOR . '..',
    'messagePath' => dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'messages',
    'languages' => ['zh_cn', 'en_us', 'ja_jp'],
    'fileTypes' => ['php'],
    'overwrite' => true,
    'exclude' => [
        '.git', '.svn', 'yiilite.php', 'yiit.php',
        '/i18n/data', '/messages', '/vendors', '/web/js',
    ],
    'translator' => 'Yii::t',
];

執行提取:

php yiic message protected/messages/config.php

生成文件結構:

protected/messages/
├── zh_cn/
│   ├── app.php
│   └── login_message.php
├── en_us/
│   └── ...
└── ja_jp/
    └── ...

4. 編輯翻譯文件

// protected/messages/zh_cn/app.php
return [
    'Welcome, {username}!' => '歡迎,{username}!',
    'Login' => '登錄',
    'Logout' => '退出',
];

// protected/messages/zh_cn/login_message.php
return [
    'username' => '用戶名',
    'password' => '密碼',
];

5. 設置應用語言

// 入口腳本 index.php (根據域名/Session/用戶偏好動態設置)
Yii::app()->language = 'zh_cn'; // 或 en_us, ja_jp

// 配置文件默認語言
'language' => 'zh_cn',
'sourceLanguage' => 'en_us', // 源代碼編寫語言

6. 複數形式處理 (CChoiceFormat)

// 訊息定義 (管道符分隔單複數形式)
$message = '{n} 條記錄|{n} 條記錄'; // 中文無單複數區別
// 英文
$message = '{n} record|{n} records';

// 使用
echo Yii::t('app', $message, ['{n}' => 1]);  // 1 條記錄 / 1 record
echo Yii::t('app', $message, ['{n}' => 5]);  // 5 條記錄 / 5 records

二、日期時間格式化:CDateFormatter

$formatter = new CDateFormatter(Yii::app()->locale);

// 預定義風格: FULL, LONG, MEDIUM, SHORT
echo $formatter->format('yyyy-MM-dd HH:mm:ss', time());        // 自定義格式
echo $formatter->formatDateTime(time(), 'medium', 'short');    // 2016年3月15日 14:30
echo $formatter->formatDateTime(time(), 'full', 'full');       // 2016年3月15日 星期二 14:30:45 CST

// 解析字符串為時間戳
$timestamp = $formatter->parse('2016-03-15 14:30:00', 'yyyy-MM-dd HH:mm:ss');

常用格式符號

符號含義示例
y年yy=16, yyyy=2016
M月M=3, MM=03, MMM=三月, MMMM=三月
d日d=5, dd=05
E星期EEE=週二, EEEE=星期二
H小時 (0-23)HH=14
h小時 (1-12)hh=02
m分mm=30
s秒ss=45
z時區CST, GMT+08:00

三、數字貨幣格式化:CNumberFormatter

$formatter = new CNumberFormatter(Yii::app()->locale);

// 數字格式化
echo $formatter->format('#,##0.00', 1234567.89);  // 1,234,567.89
echo $formatter->format('#,##0.###', 1234.5);     // 1,234.5
echo $formatter->formatPercentage(0.1234);        // 12%

// 貨幣格式化
echo $formatter->formatCurrency(12345.67, 'CNY'); // ¥12,345.67
echo $formatter->formatCurrency(12345.67, 'USD'); // $12,345.67
echo $formatter->formatCurrency(12345.67, 'EUR'); // €12,345.67

// 科學記數法
echo $formatter->format('#E0', 1234567);          // 1.23E6

貨幣符號對照

$currencies = ['CNY', 'USD', 'EUR', 'JPY', 'GBP', 'HKD', 'TWD'];
foreach ($currencies as $cur) {
    echo $cur . ': ' . $formatter->formatCurrency(100, $cur) . "\n";
}
// CNY: ¥100.00
// USD: $100.00
// EUR: €100.00
// JPY: ¥100
// GBP: £100.00
// HKD: HK$100.00
// TWD: NT$100.00

四、CLocale 區域數據深度應用

$locale = CLocale::getInstance('zh_cn'); // 或 Yii::app()->locale

// 獲取區域信息
echo $locale->getName();           // Chinese (Simplified, China)
echo $locale->getLanguage();       // zh
echo $locale->getCountry();        // CN
echo $locale->getNumberSymbols();  // 所有數字符號 (小數點、分組分隔符等)
echo $locale->getMonthNames();     // 月份名稱陣列
echo $locale->getWeekDayNames();   // 星期名稱陣列

// 日期時間格式模式
echo $locale->getDateFormat('medium');      // yyyy年M月d日
echo $locale->getTimeFormat('short');       // ah:mm
echo $locale->getDateTimeFormat('medium');  // yyyy年M月d日 ah:mm

// 貨幣信息
echo $locale->getCurrencySymbol('CNY');     // ¥
echo $locale->getCurrencyDisplayName('CNY'); // 人民幣

五、實戰最佳實踐

1. 語言自動檢測與切換

// components/LanguageSelector.php
class LanguageSelector extends CBehavior {
    public function attach($owner) {
        $owner->attachEventHandler('onBeginRequest', [$this, 'detectLanguage']);
    }
    public function detectLanguage() {
        $app = Yii::app();
        // 1. Session 優先
        if ($lang = $app->session->get('language')) {
            $app->language = $lang;
            return;
        }
        // 2. 瀏覽器 Accept-Language
        if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
            $prefs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
            foreach ($prefs as $pref) {
                $code = strtolower(substr($pref, 0, 2));
                if (in_array($code, ['zh', 'en', 'ja'])) {
                    $app->language = $code . '_' . strtoupper($code);
                    break;
                }
            }
        }
        // 3. 默認
        $app->language = $app->language ?: 'zh_cn';
    }
}

// 配置掛載
'behaviors' => ['languageSelector' => 'LanguageSelector']

2. 視圖文件按語言分離

views/
├── site/
│   ├── index.php          # 默認 (sourceLanguage)
│   ├── index.zh_cn.php    # 中文版
│   └── index.en_us.php    # 英文版

Yii 會自動根據 language 載入對應視圖,無需在控制器邏輯中判斷。

3. 數據庫內容多語言設計

-- 方案 A: 字段冗餘 (簡單、查詢快)
CREATE TABLE post (
    id INT PRIMARY KEY,
    title_zh_cn VARCHAR(255),
    title_en_us VARCHAR(255),
    body_zh_cn TEXT,
    body_en_us TEXT
);

-- 方案 B: 獨立翻譯表 (規範、擴展性強)
CREATE TABLE post (id INT PRIMARY KEY, created_at INT);
CREATE TABLE post_i18n (
    post_id INT, language VARCHAR(10), title VARCHAR(255), body TEXT,
    PRIMARY KEY (post_id, language)
);

總結

Yii 1.1 的 I18N 體系設計經典且實用:Yii::t() + PHP 陣列訊息源構建輕量翻譯流程,CLocale 封裝 600+ 區域數據,CDateFormatter/CNumberFormatter 提供專業級格式化能力。掌握「提取 → 翻譯 → 格式化」三板斧,即可將應用推向全球用戶。現代框架 (Yii 2, Laravel) 在此基礎上引入了 ICU、Gettext 等業界標準,核心思想一脈相承。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved