Python发送base64编码文件至Symfony(PHP)接口解码后为空如何解决
问题排查方向
按优先级从高到低排查以下问题点:
- 代码逻辑错误:写入文件后未重置文件指针,直接读取会从内容末尾位置开始读,必然返回空字符串;使用了不存在的
wr+文件打开模式,会导致文件句柄操作异常。 - 编码端格式错误:Python的
base64.encodebytes()返回值是bytes类型,未转成普通字符串直接做JSON序列化时,要么直接抛出序列化异常,要么会被转成带b''包裹的非标准字符串,导致PHP端拿到的内容不是合法base64格式。 - 接收端数据校验缺失:未校验接收到的原始附件内容,可能存在JSON转义截断、带
data:*/*;base64,格式前缀、混入多余空白字符等问题,直接解码会失败。 - 解码模式问题:未开启base64严格解码模式,遇到非法字符时静默失败返回空内容,无法感知解码错误。
修复方案
Python端编码修复
编码完成后必须将bytes类型转为UTF-8字符串再放入JSON结构,推荐直接用无换行的b64encode更适合接口传输:
import base64 # 方案1:用b64encode无换行编码,直接转字符串 base64_attachment = base64.b64encode(att.payload).decode('utf-8') # 方案2:如果用encodebytes,需要转字符串后去掉自动生成的换行 # base64_attachment = base64.encodebytes(att.payload).decode('utf-8').strip() arr["attachments"][att.filename] = base64_attachment # 后续正常调用json.dumps序列化发送即可
PHP/Symfony端接收修复
修正文件操作逻辑,增加数据校验步骤,Symfony中不要从$_POST取JSON内容,直接从请求对象获取原始请求体解析:
// Symfony控制器中获取请求内容示例 $requestBody = json_decode($request->getContent(), true); foreach ($requestBody['attachments'] as $fileName => $attachment) { // 清理原始base64内容 $attachment = trim($attachment); // 剥离可能存在的data URI前缀 if (str_starts_with($attachment, 'data:')) { $attachment = explode(',', $attachment, 2)[1]; } // 开启严格模式解码,解码失败返回false方便排查 $fileContent = base64_decode($attachment, true); if ($fileContent === false) { throw new \InvalidArgumentException('收到非法的base64附件内容'); } // 生成临时文件,使用合法的二进制读写模式wb+ $tmpPath = tempnam('/tmp', $fileName); $handle = fopen($tmpPath, 'wb+'); // 写入文件内容 fwrite($handle, $fileContent); // 关键:写入完成后重置文件指针到开头,否则读取为空 rewind($handle); // 读取内容验证 $readContent = fread($handle, filesize($tmpPath)); // 关闭文件句柄 fclose($handle); var_dump($readContent); // 后续业务逻辑处理 }
关键注意点
- 所有二进制文件读写操作必须使用带
b标记的模式,避免系统自动转义换行符导致文件损坏。 - 接口传输base64内容建议提前去掉换行、空白字符,减少传输体积同时降低解码失败概率。
- 文件写入操作完成后文件指针默认停留在写入内容的末尾,必须重置指针位置后再做读取操作。
内容的提问来源于stack exchange,提问作者Xbattlax
相关产品推荐
相关产品推荐

