You need to enable JavaScript to run this app. 如何使用PHP将MSSQL中存储的二进制文件导出为本地文件系统文件
优惠活动
大模型
产品
解决方案
定价
更多

如何使用PHP将MSSQL中存储的二进制文件导出为本地文件系统文件

关于存储格式的问题

你看到的0x开头的字符串是MSSQL中二进制数据的十六进制表示形式,你测试的文本Test document for migration对应的ASCII编码转十六进制后刚好就是这段内容,不需要额外做特殊编码转换,只要正确读取二进制内容写入文件即可得到原文件。

批量导出的最优实现方案

你不需要为每一行单独执行查询,也不需要强制使用sqlsrv_fetch_array,直接把现有的单文件逻辑套入sqlsrv_fetch的循环即可,这是性能最优、内存占用最低的实现方式:

// 去掉top(1)限制查询所有记录
$query = "select DESCRIPTION, FILETYPE, DOCUMENT from dbo.Documents;";
$stmt = sqlsrv_query($this->sqlsrv_conn, $query);
if ($stmt === false) {
    // 此处可添加自定义错误处理逻辑
    die(print_r(sqlsrv_errors(), true));
}

// 循环遍历每一行结果
while (sqlsrv_fetch($stmt)) {
    // 按字段索引分别指定类型读取,和单文件导出逻辑完全一致
    $document = sqlsrv_get_field($stmt, 2, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY));
    $fileName = sqlsrv_get_field($stmt, 0, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR));
    $ext = sqlsrv_get_field($stmt, 1, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR));
    
    // 流式读取写入文件,不会占用大量内存
    file_put_contents(
        $fileName . '.' . $ext,
        stream_get_contents($document),
    );
}

sqlsrv_free_stmt($stmt);

补充说明

你找不到sqlsrv_fetch_array处理不同字段类型的资料是正常的,因为这个函数本身就是用来一次性返回整行的普通类型结果的,对于二进制大字段的流式处理场景,官方本来就推荐直接用sqlsrv_fetch + sqlsrv_get_field的组合来实现,这种方式可以避免一次性把所有大文件内容加载到内存中,哪怕有几万条文件记录,运行时的内存占用也能稳定保持在很低的水平。

如果确实偏好关联数组的写法,也可以在执行查询后、遍历结果前,用sqlsrv_set_field_type预先为每个字段指定返回类型,之后再用sqlsrv_fetch_array读取就能得到符合预期的类型结果,但综合性能和可读性来看还是循环调用sqlsrv_get_field的方案更适合文件导出场景。

内容的提问来源于stack exchange,提问作者Samuel Gfeller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 02:54:03