简体   繁体   中英

How to insert file upload content to database by sending base64 encoded file content via json?

From my php page I send file upload content as

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

then send this to payload - REST API in python

$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.'"}');

then in my python code I write like this

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

Now I try inserting this to my database using sql where the image column is binary(blob) type

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 +")")

but this end in error... Am I doing in right way? or there any part missing? I dont want to save this file in any directory I just want to save this directly in db. Please help me with suggestion or any resources. Thanks in advance.

More detials is as follows

I am using adsdb python driver to connect advantage database server database.

in 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()

above use_profile is blob column type

here are the database column types

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 )

In your PHP code, after you make the call file_get_contents($_FILES['userImage']['tmp_name']) , the return value is a string containing the contents of your image, which is binary data. You should not be escaping this content as if these were actual characters. So this line should just be:

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

Therefore, in your Python code, use_pfe will be the base64-encoded image. This will be a string of ASCII characters. The line...

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

... converts use_pfe into a byte string encoded using utf-8 encoding. But, because this is Python 2 where a byte string is the same thing as a simple character string (that is, type str as opposed to a unicode string, that is, type unicode ) and the characters being encoded are from the ASCII character set, which can be encoded in a single byte, you end up with imgdata1 being identical to use_pfe . In effect, this statement does nothing. However, if this were Python 3, where byte strings, type bytes , are different from character strings, which are unicode strings, type str , this line would be incorrect: You need to leave the input as type str for input to the next line, which is converting the base64 string back to a byte string.

Putting this together:

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)

You should be doing your table insert as follows with a Prepared Statement , which not only simplifies passing the values but also avoids the possibility of SQL Injection attacks when the values are user-supplied. The place-holders for the arguments below are ? , which I believe is correct for your database (for MySql and PostgreSQL and most other relational databases, use %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))

But the above is causing:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)`

Now you must provide a complete description of every column in your table tblCode including the character set being used. Also, print out for each argument being passed, type(argument) For example:

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

But to save time, let me ask the most likely cause of the problem: Are you using a BLOB type for column use_profile ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM