sqlsrv_query查询含em dash的定长VARCHAR字段时输出中断如何解决
根因分析
该问题是SQL Server PHP驱动sqlsrv的字符集配置不匹配导致的:
你使用的VARCHAR是非Unicode单字节字段,存储em dash、en dash这类多字节字符时,编码遵循数据库默认排序规则对应的字符集(通常为GBK、Latin1等)。sqlsrv扩展默认未指定返回字符集时,会尝试按系统默认编码转码,遇到无法识别的多字节字符序列时,sqlsrv_fetch_array会直接返回false终止循环,而非输出阶段截断。这也是你没有拿到sqlsrv_errors报错的原因:转码失败属于警告级别的问题,默认不会被错误捕获接口返回,循环在执行到ID=4的记录时已经提前终止,根本没有进入后续的echo、str_replace逻辑。
解决方案
方案1(推荐):连接时指定UTF-8字符集
在数据库连接配置中明确指定返回字符集为UTF-8,驱动会自动将所有查询结果转码为合法的UTF-8字符串,从根源解决转码失败问题。修改你config.php中的连接代码即可:
$connectionInfo = array( "Database" => "你的数据库名", "UID" => "账号", "PWD" => "密码", "CharacterSet" => "UTF-8" // 新增该行配置 ); $conn = sqlsrv_connect($serverName, $connectionInfo);
方案2:手动读取二进制内容转码
如果无法修改全局连接配置,可以在查询时指定返回二进制格式,手动处理编码转换:
// 执行查询时指定返回二进制编码 $stmt = sqlsrv_query($conn, $query, array(), array( "CharacterSet" => SQLSRV_ENC_BINARY )); // 循环内手动转码,源编码替换为你数据库实际使用的编码(如GBK、CP1252等) while($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { $desc = mb_convert_encoding($row['Description'], 'UTF-8', 'GBK'); echo "<tr>"; echo "<td>".$row['ID']."</td>"; echo "<td>".$desc."</td>"; echo "</tr>"; }
方案3:修改字段类型为Unicode格式
如果业务允许修改表结构,可以将Description字段从VARCHAR(5)改为NVARCHAR(5),直接存储Unicode字符,避免编码转换问题。
之前方案无效的原因
- 调整页面字符集、
str_replace替换字符:循环在sqlsrv_fetch_array阶段就已经终止,代码未执行到输出、替换逻辑 - CAST为
VARCHAR(MAX)、LEFT截取字段:没有解决单字节存储与多字节字符的编码不匹配问题,转码失败的问题依然存在
内容的提问来源于stack exchange,提问作者Painguin
相关产品推荐
相关产品推荐

