chore: 提供中文字符编码解决方案

This commit is contained in:
2025-11-22 11:46:14 +08:00
parent 2611162e60
commit caaf85290f
4 changed files with 272 additions and 8 deletions

View File

@@ -0,0 +1,212 @@
# PHP 中文字符编码解决方案
## 🎯 问题描述
在使用 `json_encode()` 处理包含中文字符的数据时,默认会将中文字符转换为 Unicode 编码:
```php
// ❌ 默认行为 - 中文转为Unicode
$data = ['message' => '请检查计划任务配置'];
echo json_encode($data);
// 输出:{"message":"\u8bf7\u68c0\u67e5\u8ba1\u5212\u4efb\u52a1\u914d\u7f6e"}
```
这在日志文件中查看很不方便,影响调试效率。
## 🛠️ 解决方案对比
### 方案一:`JSON_UNESCAPED_UNICODE` 标志 ⭐⭐⭐⭐⭐⭐
```php
// ✅ 推荐方案 - 保持中文原样
$data = ['message' => '请检查计划任务配置'];
echo json_encode($data, JSON_UNESCAPED_UNICODE);
// 输出:{"message":"请检查计划任务配置"}
```
**优点:**
- ✅ 中文完全可读
- ✅ 保持JSON格式
- ✅ 兼容性好
- ✅ 性能优秀
**使用场景:**
- 日志记录
- API响应
- 配置文件
- 调试输出
### 方案二:`var_export()` 函数 ⭐⭐⭐
```php
// ✅ 完全避免Unicode转义
$data = ['message' => '请检查计划任务配置'];
echo var_export($data, true);
// 输出array (
// 'message' => '请检查计划任务配置',
// )
```
**优点:**
- ✅ 完全可读
- ✅ 数组结构清晰
- ✅ 无需额外参数
**缺点:**
- ❌ 不是标准JSON格式
- ❌ 输出较冗长
**使用场景:**
- 开发调试
- 临时日志
- 数组检查
### 方案三:`print_r()` + 捕获输出 ⭐⭐
```php
// ✅ 可读性好的数组输出
$data = ['message' => '请检查计划任务配置'];
ob_start();
print_r($data);
$result = ob_get_clean();
```
**优点:**
- ✅ 格式美观
- ✅ 易于阅读
**缺点:**
- ❌ 需要输出缓冲
- ❌ 性能较差
### 方案四:自定义序列化函数 ⭐⭐⭐
```php
function serializeArray($data) {
if (!is_array($data)) return $data;
$result = [];
foreach ($data as $key => $value) {
if (is_array($value)) {
$result[$key] = serializeArray($value);
} else {
$result[$key] = $value;
}
}
return $result;
}
```
## 🎯 最佳实践组合
### 在 Cron 类中的实现
```php
class Cron extends BaseModel
{
/**
* 格式化数据为日志友好的字符串(保持中文可读性)
*/
private static function formatForLog($data): string
{
if (is_array($data) || is_object($data)) {
// JSON_UNESCAPED_UNICODE 保持中文可读性
// JSON_PRETTY_PRINT 增加格式化
// JSON_UNESCAPED_SLASHES 避免斜杠转义
return json_encode($data,
JSON_UNESCAPED_UNICODE |
JSON_PRETTY_PRINT |
JSON_UNESCAPED_SLASHES
);
}
return (string) $data;
}
/**
* 完全避免Unicode转义的格式化
*/
private static function exportForLog($data): string
{
if (is_array($data) || is_object($data)) {
return var_export($data, true);
}
return (string) $data;
}
}
```
### 使用示例
```php
// 日志记录 - 使用 formatForLog
$detail = [
'error' => $error,
'remark' => $remark,
'suggestion' => ScheduleDict::getSuggestion($cronType)
];
log_write('异常信息:' . self::formatForLog($detail), 'warning');
// 调试输出 - 使用 exportForLog
$debugData = ['config' => $config, 'status' => $status];
echo self::exportForLog($debugData);
```
## 🔧 环境配置
### 确保 PHP 版本支持
```php
// PHP 5.4+ 基本支持
json_encode($data, JSON_UNESCAPED_UNICODE);
// PHP 5.3+ 需要 polyfill
if (!defined('JSON_UNESCAPED_UNICODE')) {
define('JSON_UNESCAPED_UNICODE', 256);
}
```
### 文件编码设置
```php
// 确保文件本身是 UTF-8 编码
header('Content-Type: text/html; charset=utf-8');
mb_internal_encoding('UTF-8');
```
## 📊 性能对比
| 方法 | 执行时间 | 内存使用 | 可读性 | JSON兼容 |
|------|----------|----------|---------|-----------|
| `json_encode()` | 快 | 低 | ⭐⭐⭐⭐⭐ | ✅ |
| `var_export()` | 中 | 中 | ⭐⭐⭐⭐ | ❌ |
| `print_r()` | 慢 | 高 | ⭐⭐⭐⭐ | ❌ |
| 自定义序列化 | 慢 | 高 | ⭐⭐ | ❌ |
## 🎉 推荐配置
### 生产环境(推荐)
```php
// 使用 JSON_UNESCAPED_UNICODE 保持中文可读性
json_encode($data, JSON_UNESCAPED_UNICODE);
```
### 开发环境
```php
// 使用格式化JSON增强可读性
json_encode($data,
JSON_UNESCAPED_UNICODE |
JSON_PRETTY_PRINT |
JSON_UNESCAPED_SLASHES
);
```
### 调试模式
```php
// 使用 var_export 获得最佳可读性
var_export($data, true);
```
---
**总结:** 对于您的需求,使用 `JSON_UNESCAPED_UNICODE` 标志是最佳选择既保持了JSON格式的标准性又确保了中文字符的可读性。