问题描述
$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_profile) values (?,?,?)"
cursUserAU.execute(sql,(use_cod,use_pas,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 )
解决方法
在您的 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-8
编码的字节字符串。但是,因为这是 Python 2,其中字节字符串与简单字符串(即类型 str
而不是 Unicode 字符串,即类型 unicode
)和字符相同被编码的是来自 ASCII 字符集,它可以被编码成一个字节,你最终得到 imgdata1
与 use_pfe
相同。实际上,该语句没有任何作用。但是,如果这是 Python 3,其中字节字符串,类型为 bytes
,与字符串不同,字符串是 unicode 字符串,类型为 str
,这一行将是不正确的:您需要将输入保留为输入 str
作为 next 行的输入,它将 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_ema,use_des,imgdata2))
但是上面的原因是:
UnicodeDecodeError: 'ascii' 编解码器无法解码位置 0 中的字节 0xff:序号不在范围内(128)`
现在您必须提供表 tblCode
中每一列的完整描述,包括所使用的字符集。此外,打印出每个传递的参数,type(argument)
例如:
print type(use_cod),type(use_pas),type(use_nam),... type(imgdata2)
但为了节省时间,让我问一下问题的最可能原因:您是否对列 use_profile
使用了 BLOB 类型?