В настоящее время я пытаюсь сохранить изображения из приложения 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);
}
?>
То, что вы описали, представляет собой проблему с тем, как вы пытаетесь вставить необработанные двоичные данные в базу данных. Когда вы говорите, что это работает как 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, вы столкнетесь с некоторыми ошибками в этом отношении.max_allowed_packet
.send_long_data
.