php读取sms文件防乱码需先用file_get_contents读原始字节,再用mb_convert_encoding显式转码(如'gbk'→'utf-8'),并ltrim去除utf-8 bom;csv解析须指定enclosure和escape参数,配合stream_set_encoding确保编码一致。

PHP读取SMS数据文件时怎么避免乱码
直接用 fopen() 读取短信导出文件(比如 .txt、.csv)大概率出现中文乱码,根源是编码不匹配。手机导出的SMS文本常见 GBK、GB2312 或 UTF-8 BOM,而 PHP 默认按 UTF-8 解析无BOM内容,遇到 GBK 就会崩。
- 先用
mb_detect_encoding()粗略判断,但不准,别依赖它做自动转换 - 更可靠的是:用
file_get_contents()读原始字节,再用mb_convert_encoding($content, 'UTF-8', 'GBK')显式转——前提是知道源头编码(查导出工具文档或用file -i filename.txt命令看) - 如果文件带 UTF-8 BOM(开头三个字节
),记得用ltrim($content, "")去掉,否则json_decode()或explode()可能静默失败
解析SMS CSV格式要注意字段分隔和换行嵌套
安卓短信导出的 CSV 经常把短信正文里的换行、逗号、双引号全保留,标准 fgetcsv() 默认不处理跨行字段,一读就错位。
- 必须传入第四个参数
escape,且设为"\"或空字符串(PHP 8.1+ 推荐""),否则反斜杠转义会出问题 - 调用时显式指定 enclosure 为
"""(双引号),并确保$handle = fopen($file, 'r')后立即用stream_set_encoding($handle, 'UTF-8')同步编码 - 示例安全读法:
$handle = fopen('sms.csv', 'r'); stream_set_encoding($handle, 'UTF-8'); while (($row = fgetcsv($handle, 0, ',', '"', '')) !== false) { $phone = $row[0] ?? ''; $body = $row[2] ?? ''; }
写入SMS数据到MySQL要防SQL注入和时间格式错乱
把解析后的短信存进数据库,最常踩的坑不是逻辑,而是 datetime 字段写入失败或时区偏移——手机导出的时间戳多为本地时间(如 "2024-03-15 14:22:05"),没带时区信息。
- 别用
date('Y-m-d H:i:s')直接拼字符串插库;改用new DateTime($raw_time)实例化后再调format('Y-m-d H:i:s'),它会按当前date_default_timezone_set()解析 - 插入前务必用
mysqli_real_escape_string()或预处理语句——body字段含单引号、 、emoji 时,裸字符串拼接必炸 - 如果原始时间是“13:22:05”,但没日期,得补上当天日期再构造
DateTime,否则变成 1970 年
用PHP发送SMS回执需要校验手机号和内容长度
处理完读取和存储,下一步常是自动回复(比如关键词触发)。这时 curl 调用短信网关 API 前,必须拦截两类硬伤。
- 手机号格式:用
preg_match('/^1[3-9]d{9}$/', $phone)过滤,去掉空格、短横、括号;国际号另说,但国内场景别信用户输入 - 短信内容超长:中文按 70 字符/条计(含签名),超过就得拆。用
mb_strlen($text, 'UTF-8')算真实长度,别用strlen() - 签名必须前置且加【】,比如
【我的APP】您好,漏掉或格式错,运营商直接拒收
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











