
本文介绍如何在 PHP 中读取 JSON 格式的多语言文件,并安全、灵活地将运行时变量(如用户名)注入到带占位符的翻译字符串中,核心方法是结合 json_decode() 与 str_replace() 或 sprintf() 实现模板化文本渲染。
本文介绍如何在 php 中读取 json 格式的多语言文件,并安全、灵活地将运行时变量(如用户名)注入到带占位符的翻译字符串中,核心方法是结合 `json_decode()` 与 `str_replace()` 或 `sprintf()` 实现模板化文本渲染。
在国际化(i18n)开发中,将语言文本抽离为 JSON 文件是一种轻量且可维护的做法。但原生 JSON 不支持变量插值——它只是静态数据格式。因此,关键不在于“让 JSON 包含 PHP 变量”,而在于“用 PHP 动态渲染 JSON 中的模板字符串”。
以下是一个完整、生产可用的实现方案:
✅ 正确做法:JSON 存模板,PHP 负责渲染
首先,保持 lang/en.json 纯净、无逻辑:
{
"user": {
"hello": "Hello {name}",
"welcome_back": "Welcome back, {name}! Last login: {date}",
"profile_title": "Profile of {name}"
},
"error": {
"not_found": "Resource '{id}' was not found."
}
}然后在 PHP 中加载并安全替换占位符:
立即学习“PHP免费学习笔记(深入)”;
<?php
// 1. 加载并解码 JSON(推荐使用关联数组,更易操作)
$json = file_get_contents('lang/en.json');
$lang = json_decode($json, true); // 第二个参数 true → 返回 array 而非 object
// 2. 定义一个通用消息渲染函数
function msg(string $template, array $params = []): string {
$output = $template;
foreach ($params as $key => $value) {
$output = str_replace("{" . $key . "}", htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'), $output);
}
return $output;
}
// 3. 使用示例
$username = 'rawohah211';
echo msg($lang['user']['hello'], ['name' => $username]);
// 输出:Hello rawohah211
echo msg($lang['user']['welcome_back'], [
'name' => 'Alice',
'date' => date('Y-m-d H:i')
]);
// 输出:Welcome back, Alice! Last login: 2024-06-15 14:22
?>? 安全注意事项
- 永远对用户输入做转义:如上例中使用 htmlspecialchars() 防止 XSS(尤其当变量用于 HTML 上下文时);
- 避免直接 eval() 或 sprintf 无约束使用:sprintf 要求严格匹配占位符类型(如 %s, %d),灵活性低且易出错;str_replace 更直观可控;
-
健壮性增强建议:
- 添加占位符缺失检测(如 if (!isset($params[$key])) { throw new InvalidArgumentException("Missing param: {$key}"); });
- 支持嵌套键(如 {user.name})可借助 preg_replace_callback 扩展,但多数场景简单 {key} 已足够。
? 总结
- JSON 是数据格式,不是模板引擎——不要试图在 JSON 内写 PHP 语法或变量;
- 真正的“变量注入”发生在 PHP 层:先解析 JSON 为数组/对象,再用字符串替换完成动态渲染;
- 推荐统一使用关联数组(json_decode($json, true))+ str_replace 组合,简洁、安全、易测试;
- 如需更强大能力(复数、性别、上下文翻译),应升级至专业 i18n 库(如 symfony/translation 或 gettext),而非自行扩展 JSON 模板逻辑。
通过这一模式,你既能享受 JSON 的可读性与前端兼容性,又能保有 PHP 的动态控制力。











