PHP连接SQL Server 2008插入中文乱码解决方案
在开发过程中,将数据库的默认编码识别为GB2312或GBK是常见的误区。当PHP脚本采用UTF-8编码且使用微软提供的sqlsrv驱动连接SQL Server 2008时,直接传递中文字符串极易引发底层UTF-16转换异常。解决该问题的核心在于:放弃无效的Set Names命令,改用PHP内置函数强制转换字符集,并确保SQL语法中字段的字符串值被正确引用。
问题分析与准备条件
在使用 php 5.3.3、Apache 2.2.17 与 SQL Server 2008 的组合环境中,开发者的PHP源文件通常遵循 UTF-8 编码标准。早期的MSSQL扩展(如 mssql.dll)已不再受支持,现代连接必须依赖微软官方维护的 sqlsrv 扩展库。
当尝试执行如下代码时:
$conn = sqlsrv_connect($serverName, $connectionInfo); // 假设为有效连接$sql = "insert into Opinion (content) values ('aaa中文内容')";sqlsrv_query($conn, $sql);系统往往会报错。其根本原因在于 sqlsrv 驱动内部要求以 UTF-16 格式与SQL Server通信。如果传入的是未经处理的 UTF-8 字节流,驱动程序在尝试将其转码时会发生不可逆的错误,而非简单的显示乱码。
错误排查过程
在修复过程中,开发者通常会经历以下三个错误的阶段,明确这些错误有助于理解最终方案:
第1步:尝试设置会话编码失败
为了匹配所谓的“默认编码”,尝试在查询前加入编码声明:sqlsrv_query($conn, "set names GB2312");
此举会导致驱动直接抛出严重错误,提示无法将查询字符串转换为UTF-16。此类报错信息中夹杂大量不可读符号(如 Array ( [0] => Array ( [0] => IMSSP ... ) )),确认了编码转换层面的阻碍。
第2步:引入字符转换但忽略语法结构
随后引入 iconv 函数进行中转,尝试将 UTF-8 强制转为 GB2312:
$string = iconv('utf-8', 'GB2312//IGNORE', 'aaa中文内容');$sql = "insert into Opinion (content) values ( $string)";此时虽然解决了编码转换错误,却会触发新的SQL语法错误([Microsoft][SQL Server Native Client 10.0][SQL Server]... 'aaa中文'...)。检查生成的SQL语句会发现:
insert into Opinion (content) values ( aaa中文)由于 $string 变量未被包含在任何引号内,解析器将其视为列名或保留字,导致插入失败。
正确的操作顺序
第1步:对字符串执行精准的编码转换
目的:确保传递给驱动的数据块符合 sqlsrv 预期的二进制流特征。即便SQL Server端接受GB2312,从PHP环境出发,需显式声明转化路径。
动作:
- 提取需要入库的原始中文字符串变量。
- 调用PHP的
iconv函数,指定输入为'utf-8',输出为'gbk'(推荐)或'gb2312',并添加'//IGNORE'参数以防止非法字符导致截断。
第2步:完善SQL语句的引用包裹
目的:修正拼接字符串时丢失的边界界定符。
动作:
- 在拼接
INSERT INTO语句时,务必为参与运算的变量加上单引号。 - 最终生成的
$sql应为:
$string = iconv('utf-8', 'gbk//IGNORE', '您的中文字段内容');$sql = "insert into Opinion (content) values ('" . $string . "')";完成判断
执行上述修正后的代码后,控制台不应再返回错误数组(即 sqlsrv_errors() 为空)。前往SQL Server数据库查看 Opinion 表中的 content 字段,中文字符能够完整显示而无替换符号(???),即表示成功解决。
总结
PHP结合SQL Server操作时的乱码与报错,往往不是单一编码设置所能解决的复杂问题。关键在于认清微软 sqlsrv 驱动对 UTF-16 的特殊要求,通过 iconv 做缓冲层处理,同时严加防范字符串拼接时的语法漏洞。以上就是PHP向SQL Server 2008写入中文内容的详细内容,更多关于PHP连接SQL Server中文乱码的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









