base64_decode не работает для PHP

0

В настоящее время я пытаюсь сохранить изображения из приложения Android. Приложение преобразует изображение из объекта ImageView в массив байтов, а затем использует Android, встроенный в функцию Base64.encodeToString, чтобы я мог передать его в HTTP-запрос на свой PHP-скрипт (который ведет логику "Вставить в базу данных").

По какой-то причине, если в моем PHP-скрипте я пытаюсь вызвать base64_decode перед сохранением изображения в качестве MEDIUMBLOB, весь процесс вставки завершится неудачно, но если я пропущу base64_decode в PHP-скрипте, вставка успешно работает. Может ли кто-нибудь объяснить мне, почему? Была отладка в течение нескольких часов, но, похоже, не может найти причину

Я думал, что это расшифровка поможет мне сохранить место на БД. Я знаю, что не хранил изображения в БД и не использовал пути и прочее, но для своей текущей цели я решил сохранить его в БД, поскольку он намного удобнее для меня (это не огромный масштабируемый проект, поскольку я просто разрабатываю что-то для небольшого исследования).

Заранее спасибо!

<?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);
    }
    ?>
  • 0
    При вставке вы убегаете / готовитесь?
  • 0
    Также я просто получаю значения напрямую из $ _POST (для прямого подхода). Затем я попытался бы вызвать base64_decode для переменной (которая не работает), но работает, если я не вызываю base64_decode для нее
Показать ещё 4 комментария
Теги:
image
blob

1 ответ

1
Лучший ответ

То, что вы описали, представляет собой проблему с тем, как вы пытаетесь вставить необработанные двоичные данные в базу данных. Когда вы говорите, что это работает как base64, это потому, что base64 обычно не будет содержать в себе один кавычек, который разбивает запрос sql, который вы показываете.

Чтобы избежать значения, используя те старые функции mysql_*, вы должны использовать mysql_escape_string...

Не используйте этот старый метод mysql!

Вы должны перейти на mysqli, который существует уже много лет (ваш сервер должен его поддерживать). Поскольку, похоже, ваш метод DB_CONNECT построен вокруг старого mysql, вам придется реструктурировать его для mysqli. Это не слишком сложно.

Я могу предоставить вам пример того, как сделать вставку 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();

Это относится к последнему значению как прямому транзиту в виде "строки" в поле MEDIUMBLOB должно быть надежно вставлено (а также безопасно обрабатывать другие три переменные, защищающие вас от атак с SQL-инъекциями).

Альтернативным способом отправки двоичных данных в пакетах является следующий метод:

$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();

Некоторые примечания:

  • Если ваши изображения больше, чем max_allowed_packet mysql, вы столкнетесь с некоторыми ошибками в этом отношении.
  • Если ваше поле является BLOB, оно будет содержать только изображение <64kb. Если его MEDIUMBLOB будет содержать изображение 16 МБ, но вы рискуете запустить его через max_allowed_packet.
  • Если вы запускаете проблему с пакетом, вам нужно будет создать петлю пакетов, чтобы пропускать меньшие куски через функцию send_long_data.
  • 0
    Cheers IncredibleHat, я попытаюсь использовать набор функций mysqli и посмотреть, работает ли он
  • 0
    Тем временем вы можете попробовать mysql_escape_string ... просто чтобы посмотреть, сможете ли вы заставить это работать.
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню