# 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格式的标准性,又确保了中文字符的可读性。