首页 > 解决方案 > 如何通过json发送base64编码的文件内容将文件上传内容插入数据库?

问题描述

从我的 php 页面我发送文件上传内容为

$imgData = addslashes(file_get_contents($_FILES['userImage']['tmp_name']));
$imgData= base64_encode($imgData);

然后将其发送到有效负载-python中的REST API

$call->send('{"payload" : { "dbstr" :"' . DEF_DB . '", "tblCode" : "' . USE_INF . '", "use_cod": "'.$use_cod.'", "use_pas": "'.$use_pas.'","use_nam": "'.$use_nam.'","use_dob": "'.$use_dob.'","use_ema": "'.$use_ema.'","use_des": "'.$use_des.'","use_pfe": "'.$imgData.'"}');

然后在我的python代码中我这样写

use_pfe = item_dict['payload']['use_pfe']
imgdata1 = use_pfe.encode("utf-8")
imgdata2 = base64.b64decode(imgdata1)

现在我尝试使用 sql 将其插入到我的数据库中,其中图像列是二进制(blob)类型

cursUserAU.execute("insert into " + tblCode + " (use_cod, use_pass, use_nam, use_dob, use_email, use_desig, use_profile) values ('" + use_cod +"' , '"+ use_pas +"', '"+ use_nam +"', '"+ use_dob +"', '"+ use_ema +"', '"+ use_des +"', "+ imgdata2 +")")

但这以错误告终……我做得对吗?还是缺少任何部分?我不想将此文件保存在任何目录中,我只想将其直接保存在 db 中。请帮助我提出建议或任何资源。提前致谢。

更多详情如下

我正在使用 adsdb python 驱动程序连接优势数据库服务器数据库。

在蟒蛇

connUserAU = adsdb.connect(DataSource=datasource, ServerType='3', UserID='adssys', Password='')
cursUserAU = connUserAU.cursor()
sql = "insert into " + tblCode + " (use_cod, use_pass, use_nam, use_dob, use_email, use_desig, use_profile) values (?, ?, ?, ?, ?, ?, ?)"
cursUserAU.execute(sql, (use_cod, use_pas, use_nam, use_dob, use_ema, use_des, imgdata))
connUserAU.commit()
cursUserAU.close()

上面的 use_profile 是 blob 列类型

这是数据库列类型

use_cod Char( 10 ),
use_pass Char( 10 ),
use_nam Char( 30 ),
use_dob Date,
use_email Char( 50 ),
use_desig Char( 30 ),
use_profile Blob,
user_gender Char( 1 ),
use_profile2 CIChar( 50 )

标签: phpsqljsonpython-2.7advantage-database-server

解决方案


在您的 PHP 代码中,调用之后file_get_contents($_FILES['userImage']['tmp_name']),返回值是一个包含图像内容的字符串,它是二进制数据。你不应该逃避这个内容,就好像这些是实际的字符一样。所以这条线应该是:

$imgData = file_get_contents($_FILES['userImage']['tmp_name']);

因此,在您的 Python 代码中,use_pfe将是 base64 编码的图像。这将是一串 ASCII 字符。线...

imgdata1 = use_pfe.encode("utf-8")

... 转换use_pfe为使用utf-8encoding 编码的字节字符串。但是,因为这是 Python 2,其中字节字符串与简单字符串(即 typestr而不是 unicode 字符串,即 type unicode)相同,并且被编码的字符来自 ASCII 字符集,其中可以用一个字节编码,你最终imgdata1会与use_pfe. 实际上,这个语句什么也没做。但是,如果这是 Python 3,其中字节字符串 typebytes与字符串不同,后者是 unicode 字符串 type str,则此行将不正确:您需要将输入保留为 typestr以便输入到下一行,即将 base64 字符串转换回字节字符串。

把它放在一起:

PHP:

$imgData = file_get_contents($_FILES['userImage']['tmp_name']);
$imgData = base64_encode($imgData);

Python:

use_pfe = item_dict['payload']['use_pfe']
imgdata2 = base64.b64decode(use_pfe)

您应该使用Prepared Statement如下进行表插入,这不仅简化了值的传递,而且还避免了在用户提供值时发生 SQL 注入攻击的可能性。以下参数的占位符是?,我认为这对您的数据库是正确的(对于 MySql 和 PostgreSQL 以及大多数其他关系数据库,使用%s)。

# make it more readable:
sql = "insert into " + tblCode + " (use_cod, use_pass, use_nam, use_dob, use_email, use_desig, use_profile) values (?, ?, ?, ?, ?, ?, ?)"
cursUserAU.execute(sql, (use_cod, use_pas, use_nam, use_dob, use_ema, use_des, imgdata2))

但以上原因导致:

UnicodeDecodeError:“ascii”编解码器无法解码位置 0 的字节 0xff:序数不在范围内(128)`

现在您必须提供表中每一列的完整描述,tblCode包括所使用的字符集。此外,打印出每个传递的参数,type(argument)例如:

print type(use_cod), type(use_pas), type(use_nam), ... type(imgdata2)

但是为了节省时间,让我问一下问题的最可能原因:您使用的是 BLOB 类型的 columnuse_profile吗?


推荐阅读