从MySQL下载二进制可执行文件时文件大小异常的技术求助
解决MySQL大BLOB文件下载不完整问题
问题原因分析
下载文件仅1MB的核心原因包括:
- PDO默认读取逻辑会截断大BLOB数据
strlen()遇到二进制中的\0字符会停止计算,导致Content-Length值错误- 输出缓冲区残留的无关内容会干扰二进制文件输出
- 数据库字段类型不支持大文件存储(比如用了
BLOB而非MEDIUMBLOB)
解决方案
1. 确保数据库字段支持大文件存储
先检查download表的File字段类型:
BLOB最大仅支持64KB存储MEDIUMBLOB最大支持16MB(适配你的13MB文件)LONGBLOB最大支持4GB
如果当前字段是BLOB,执行SQL修改:
ALTER TABLE download MODIFY COLUMN File MEDIUMBLOB;
2. 修改PHP代码实现完整下载
include_once 'dbconnect.php'; // 用参数绑定避免SQL注入,同时保证查询准确性 $query = "SELECT File FROM download WHERE username = :username"; $stmt = $conn1->prepare($query); $stmt->bindParam(':username', $username); $stmt->execute(); // 绑定BLOB字段,指定PARAM_LOB类型确保完整读取大对象 $stmt->bindColumn(1, $blob, PDO::PARAM_LOB); $stmt->fetch(PDO::FETCH_BOUND); // 按原始字节数计算文件长度,避免null字符截断计数 $fileSize = mb_strlen($blob, '8bit'); // 设置响应头 header("Content-type: application/octet-stream"); header("Content-Disposition: attachment; filename=download.exe"); header("Content-length: " . $fileSize); // 清空输出缓冲区并刷新,防止残留内容污染二进制文件 ob_clean(); flush(); // 输出完整二进制数据 echo $blob; exit;
关键修改说明
- 参数绑定:替代字符串拼接写法,彻底避免SQL注入风险,同时保证查询逻辑稳定
bindColumn+PDO::PARAM_LOB:明确告知PDO读取大对象数据,不会自动截断内容mb_strlen('8bit'):按原始字节数计算长度,不受二进制中的控制字符影响ob_clean()+flush():清除之前页面输出的缓存内容(比如dbconnect.php中可能存在的空白字符),确保输出的只有目标二进制文件
内容的提问来源于stack exchange,提问作者Rover1337
相关产品推荐
相关产品推荐

