简体   繁体   English

base64_decode对PHP不起作用

[英]base64_decode not working for PHP

I currently am trying to store images from an Android application. 我目前正在尝试存储来自Android应用程序的图像。 The app converts the image from the ImageView object into a byte array and then uses Android's built in Base64.encodeToString function so that I could pass it within a HTTP Post Request to my PHP script(which conducts the Insert to Database logic). 该应用程序将图像从ImageView对象转换为字节数组,然后使用Android内置的Base64.encodeToString函数,这样我就可以在HTTP Post Request中将其传递给我的PHP脚本(该脚本执行插入数据库的逻辑)。

For some reason, if in my PHP Script I try to call base64_decode before storing the image as a MEDIUMBLOB, the whole insertion process fails but if I skip the base64_decode within the PHP script, the insertion works successfully. 由于某种原因,如果在我的PHP脚本中尝试在将映像存储为MEDIUMBLOB之前调用base64_decode,则整个插入过程将失败,但是如果我跳过PHP脚本中的base64_decode,则插入成功。 Could anyone explain to me why? 谁能向我解释为什么? Been debugging for hours but can't seem to find out the reason 调试了几个小时,但似乎找不到原因

I was thinking that decoding it would help me save storage space on the DB. 我当时认为解码它可以帮助我节省数据库上的存储空间。 I'm aware of not storing images in DBs and using paths and stuff but for my current purpose, I've chosen to store it in the DB as it's much more convenient for me (it's not a huge scalable project as I am just developing something to run for a small study). 我知道没有将图像存储在数据库中并使用路径和内容,但是出于当前的目的,我选择将其存储在数据库中,因为它对我来说更加方便(这不是一个巨大的可扩展项目,因为我正在开发中进行小型研究的东西)。

Thanks in advance! 提前致谢!

<?php

    /*
    * Following code will create a new product row
    * All product details are read from HTTP Post Request
    */

    // array for JSON response
    $response = array();

    // check for required fields
    if (isset($_POST['username']) && isset($_POST['drinkName']) && isset($_POST['caption']) && isset($_POST['photo']) ) 
    {

    $username = $_POST['username'];
    $drinkName = $_POST['drinkName'];
    $caption = $_POST['caption'];

    $photoRaw = $_POST['photo'];    
    $photo = base64_decode($photoRaw);

    // include db connect class
    require_once __DIR__ . '/db_connect.php';

    // connecting to db
    $db = new DB_CONNECT();

    // mysql inserting a new row
    $result = mysql_query("INSERT INTO Memories(username, drinkName, caption, photo) VALUES('$username', '$drinkName', '$caption', '$photo')");
    // check if row inserted or not
    if ($result) {
    // successfully inserted into database
    $response["success"] = 1;
    $response["message"] = "Product successfully created.";
    // echoing JSON response
    echo json_encode($response);
    } else {
    // failed to insert row
    $response["success"] = 0;
    $response["message"] = "Oops! An error occurred.";

    // echoing JSON response
    echo json_encode($response);
    }
    } else {
    // required field is missing
    $response["success"] = 0;
    $response["message"] = "Required field(s) is missing";

    // echoing JSON response
    echo json_encode($response);
    }
    ?>

What you have described is a problem with how you are trying to insert the raw binary data into the database. 您所描述的是如何尝试将原始二进制数据插入数据库中的问题。 When you say it works as base64, that is because base64 generally won't have a single-quote character in it which would break the sql query you show you are using. 当您说它可以用作base64时,这是因为base64通常不会在其中包含单引号字符,这会破坏您所显示的SQL查询。

To escape the value using those old mysql_* functions, you would use mysql_escape_string ... 要使用那些旧的mysql_*函数转义该值,可以使用mysql_escape_string ...

Please do not use that old mysql method! 请不要使用旧的mysql方法!

You should migrate to mysqli which has been around for many years (your server should support it). 您应该迁移到已经存在很多年的mysqli (您的服务器应该支持它)。 Since it looks like your DB_CONNECT method is built around the old mysql, you will have to restructure that for mysqli. 由于看起来您的DB_CONNECT方法是围绕旧mysql构建的,因此您将不得不为mysqli重构它。 Its not too difficult. 它不太困难。

I can provide you with an example of how to do the mysqli insert using a safely prepared statement: 我可以为您提供一个如何使用安全准备的语句进行mysqli插入的示例:

$mysqli = new mysqli("localhost", "my_user", "my_password", "db_name");// db connect
$stmt = $mysqli->prepare("INSERT INTO Memories (username, drinkName, caption, photo) 
                          VALUES(?,?,?,?)");
$stmt->bind_param("ssss", $username, $drinkName, $caption, $photo);
$stmt->execute();

This treats the last value as a straight passthrough as a 'string' into your MEDIUMBLOB field to be inserted safely (as well as safely handle the other three variables protecting you from sql injection attacks). 这会将最后一个值作为“字符串”直接MEDIUMBLOB给您的MEDIUMBLOB字段,以安全地插入(以及安全处理其他三个变量来保护您免受sql注入攻击)。

An alternate way to send binary data in, in packets, is this method: 以数据包形式发送二进制数据的另一种方法是这种方法:

$mysqli = new mysqli("localhost", "my_user", "my_password", "db_name");// db connect
$stmt = $mysqli->prepare("INSERT INTO Memories (username, drinkName, caption, photo) 
                          VALUES(?,?,?,?)");
$null = NULL;   // this is just a holder to bind on
$stmt->bind_param("sssb", $username, $drinkName, $caption, $null); // note the 'b'
$stmt->send_long_data(3,$photo);   // 3 indicates the 4th bound variable
$stmt->execute();

Some notes: 一些注意事项:

  • If your images are bigger than the max_allowed_packet of mysql, you will run into some errors in that regard. 如果您的映像大于mysql的max_allowed_packet ,则在这方面会遇到一些错误。
  • If your field is a BLOB it would only hold an image < 64kb. 如果您的字段是BLOB,则只能保存<64kb的图像。 If its MEDIUMBLOB it will hold a 16mb image, but you risk run over max_allowed_packet . 如果它是MEDIUMBLOB,它将保存一个16mb的图像,但是您可能会运行max_allowed_packet
  • If you run over the packet issue, you would need to build a packet loop to pass smaller chunks through the send_long_data function. 如果遇到数据包问题,则需要构建一个数据包循环,以通过send_long_data函数传递较小的块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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