PHP读取SQL Server存储过程返回JSON被截断为2032字节如何解决
问题根因说明
你遇到的2033字节截断不是PHP字符串的长度限制,PHP字符串最大长度仅受memory_limit配置约束,默认配置下支持数百兆的单个字符串,完全不存在2KB级别的上限。问题本质是SQL Server的FOR JSON特性默认将返回的大JSON拆分为多个长度不超过2033字节的行,PHP驱动如果只读取第一行就会出现截断。
解决方案
方案1:修改SQL查询(优先推荐)
将FOR JSON的结果先赋值给NVARCHAR(MAX)类型变量再返回,即可强制SQL Server将完整JSON作为单条结果返回,修改后的查询示例如下:
DECLARE @JsonResult NVARCHAR(MAX) SET @JsonResult = ( SELECT V.* FROM ClassPerson CP INNER JOIN PersonActive PA ON (CONVERT(nvarchar(128), PA.PersonActiveId) = @usrGuid AND CP.PersonId = PA.personId) INNER JOIN ClassPerson CP2 ON (CP2.classId = CP.ClassId) INNER JOIN V_Student V ON (V.PersonId = CP2.PersonId) FOR JSON PATH, ROOT('AllRecord') ) SELECT @JsonResult AS FullJson
方案2:调整PHP驱动配置
如果使用微软官方的sqlsrv/pdo_sqlsrv扩展,可调整以下配置避免大文本截断:
- 针对sqlsrv扩展:
// 全局配置客户端缓冲区大小为10M,可根据业务需求调整 sqlsrv_configure('ClientBufferMaxKBSize', 10 * 1024); // 连接时指定字符集为UTF-8 $conn = sqlsrv_connect($serverName, [ 'Database' => $dbName, 'UID' => $user, 'PWD' => $pwd, 'CharacterSet' => 'UTF-8' ]); - 针对PDO_SQLSRV扩展:
$pdo = new PDO("sqlsrv:Server=$serverName;Database=$dbName", $user, $pwd); // 设置编码为UTF-8 $pdo->setAttribute(PDO::SQLSRV_ATTR_ENCODING, PDO::SQLSRV_ENCODING_UTF8); // 设置客户端缓冲区大小为10M $pdo->setAttribute(PDO::SQLSRV_ATTR_CLIENT_BUFFER_MAX_KB_SIZE, 10 * 1024);
方案3:手动拼接结果片段
如果不方便修改存储过程,可以在PHP侧读取所有返回的结果行,将每行的字符串拼接起来得到完整JSON:
$fullJson = ''; while($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_NUMERIC)) { $fullJson .= $row[0]; } // 后续再解析$fullJson即可
其他注意事项
如果仍在使用已经废弃的mssql扩展,建议立即更换为微软官方维护的sqlsrv/pdo_sqlsrv扩展,旧扩展对大文本、UTF-8的支持存在较多已知问题。
内容的提问来源于stack exchange,提问作者Davis N.
相关产品推荐
相关产品推荐

