PHP 怎么PHP本地化项目

wen PHP项目 2

本文目录导读:

PHP 怎么PHP本地化项目

  1. gettext 扩展(最专业,适合大型项目)
  2. 数组/JSON 文件(最简单,适合中小项目)
  3. 使用第三方库(省时省力)
  4. 数据库存储(适合动态内容)
  5. 现代框架自带方案
  6. 实战建议

在 PHP 项目中实现本地化(i18n),主要有 5 种主流方案,根据项目规模和需求选择:


gettext 扩展(最专业,适合大型项目)

这是 Linux 系统最标准的本地化方案,支持复数、上下文等复杂语法。

// 1. 初始化
putenv('LANG=zh_CN.utf8');
setlocale(LC_ALL, 'zh_CN.utf8');
bindtextdomain('messages', './locale');
textdomain('messages');
// 2. 使用
echo gettext("Hello World");
// 或短函数
echo _("Hello World");

准备翻译文件

  • 需要安装 gettext 工具生成 .po.mo 文件
  • 结构:./locale/zh_CN/LC_MESSAGES/messages.mo

优点:性能最好,支持复数规则
缺点:需要服务器安装 gettext 扩展,配置文件较复杂


数组/JSON 文件(最简单,适合中小项目)

最常用的轻量级方案,把翻译放在 PHP 数组或 JSON 文件中。

// lang/zh.php
return [
    'welcome' => '欢迎光临',
    'hello' => '你好,:name',
    'items_count' => '{0} 没有项目|{1} 一个项目|[2,*] :count 个项目',
];
// 使用
$translations = require "lang/{$lang}.php";
echo $translations['welcome']; // 欢迎光临
// 动态替换
$name = 'John';
echo str_replace(':name', $name, $translations['hello']);

最优实践:封装成类

class Translator {
    private $translations = [];
    public function __construct($lang) {
        $this->translations = require "lang/{$lang}.php";
    }
    public function trans($key, $params = []) {
        $text = $this->translations[$key] ?? $key;
        foreach ($params as $k => $v) {
            $text = str_replace(":{$k}", $v, $text);
        }
        return $text;
    }
    // 支持复数
    public function transChoice($key, $count, $params = []) {
        $rules = explode('|', $this->translations[$key]);
        // 简单的复数逻辑
        $index = $count == 1 ? 1 : 2;
        $text = $rules[$index] ?? $rules[0];
        return str_replace(':count', $count, $text);
    }
}

使用第三方库(省时省力)

Symfony Translation 组件

composer require symfony/translation
use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\Loader\PhpFileLoader;
$translator = new Translator('zh_CN');
$translator->addLoader('php', new PhpFileLoader());
$translator->addResource('php', __DIR__.'/lang/zh.php', 'zh_CN');
echo $translator->trans('welcome');
echo $translator->trans('items_count', ['%count%' => 5]);

Laravel 风格的简单实现

// 使用框架的 __() 函数
__('messages.welcome');
__('messages.order_count', ['count' => 5]);

数据库存储(适合动态内容)

适合需要在线修改翻译的场景。

CREATE TABLE translations (
    id INT PRIMARY KEY AUTO_INCREMENT,
    key VARCHAR(255) UNIQUE,
    locale VARCHAR(10),
    value TEXT
);
class DBTranslator {
    private $cache = [];
    public function trans($key, $locale = 'zh') {
        if (!isset($this->cache[$locale])) {
            // 加载该语言的所有翻译到缓存
            $this->cache[$locale] = $this->loadFromDB($locale);
        }
        return $this->cache[$locale][$key] ?? $key;
    }
}

现代框架自带方案

如果你在 Laravel / Symfony 等框架中,直接使用内置功能:

Laravel 示例

// 创建语言文件
// resources/lang/zh/messages.php
// 使用
echo __('messages.welcome');
echo trans_choice('messages.items', $count);

Symfony 示例

// translations/messages.zh_CN.yaml
// 使用
echo $this->translator->trans('welcome');

实战建议

✅ 推荐组合方案:

  • 小项目:使用 数组/JSON + 封装类
  • 中大型项目gettextSymfony Translation 组件
  • 框架项目:直接用框架内置 i18n

📁 目录结构建议:

project/
├── lang/
│   ├── zh.php
│   ├── en.php
│   └── fr.php
├── locale/           # gettext 文件
│   ├── zh_CN/LC_MESSAGES/messages.mo
│   └── en_US/LC_MESSAGES/messages.mo
└── src/
    └── Translator.php

🎯 最佳实践:

  1. 语言检测:根据 Accept-Language 或用户选择
  2. 语言包缓存:使用 APCu/Redis 缓存翻译数据
  3. 翻译键规范:使用 模块.功能.具体操作 格式(user.login.success
  4. 占位符统一:统一使用 param 格式

选择适合你项目规模的方案,复杂度越高收益越大,小项目别过度设计!

抱歉,评论功能暂时关闭!