I try to upload a file from html-form in my mariadb database booksummerytable. I get an db entry in the table, in columns student_id and a book_id, but the file-entry just do not want pass in the LONGBLOB column for the file.
<?php
session_start();
if ($_SESSION["rolle"] === "schueler" && isset($_GET['id'])) {
$buchId = $_GET['id'];
$dbHost = '...';
$dbUser = '...';
$dbPass = '...';
$dbName = '...';
$conn = new mysqli($dbHost, $dbUser, $dbPass, $dbName);
if ($conn->connect_error) {
die("Verbindung zur Datenbank fehlgeschlagen: " . $conn->connect_error);
}
// Wiederholen Sie Ihre Datenbankabfrage, um die Buchinformationen zu erhalten
$sql = "SELECT title FROM buecher WHERE id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $buchId);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows == 1) {
$row = $result->fetch_assoc();
$buchtitel = $row['title'];
// Hier fügen wir das Formular zum Hochladen der Zusammenfassung hinzu
echo '<h2>Zusammenfassung für das Buch: ' . $buchtitel . '</h2>';
echo '<form action="upload_zusammenfassung.php" method="post" enctype="multipart/form-data">';
echo ' <input type="file" name="zusammenfassung" id="zusammenfassung">';
echo ' <input type="hidden" name="buch_id" value="' . $buchId . '">';
echo ' <input type="submit" value="Zusammenfassung hochladen">';
echo '</form>';
} else {
echo "Buch nicht gefunden.";
}
$stmt->close();
}
?>
Anothe file, where happen the db-entry
<?php
error_reporting(E_ALL);
session_start();
if ($_SESSION["rolle"] === "schueler" && isset($_FILES['zusammenfassung']) && isset($_POST['buch_id'])) {
// Verbindung zur Datenbank herstellen
$dbHost = '...';
$dbUser = '...';
$dbPass = '...';
$dbName = '...';
$conn = new mysqli($dbHost, $dbUser, $dbPass, $dbName);
if ($conn->connect_error) {
die("Verbindung zur Datenbank fehlgeschlagen: " . $conn->connect_error);
}
$buchId = $_POST['buch_id'];
// Dateiinformationen
$dateiTmpName = $_FILES['zusammenfassung']['tmp_name'];
$dateiDaten = file_get_contents($dateiTmpName);
// Schüler-ID aus der Datenbank anhand des Benutzernamens holen
$schuelerBenutzername = $_SESSION["username"];
$sqlSchuelerId = "SELECT id_student FROM students WHERE newUsername = ?";
$stmtSchuelerId = $conn->prepare($sqlSchuelerId);
$stmtSchuelerId->bind_param("s", $schuelerBenutzername);
$stmtSchuelerId->execute();
$stmtSchuelerId->bind_result($schuelerId);
$stmtSchuelerId->fetch();
$stmtSchuelerId->close();
// SQL-Befehl, um die Zusammenfassung in der Datenbank zu speichern
$sql = "INSERT INTO buchzusammenfassung (idSchueler, idBuch, datei) VALUES (?, ?, ?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param("iib", $schuelerId, $buchId, $dateiDaten);
if ($stmt->execute()) {
echo "Die Zusammenfassung wurde erfolgreich hochgeladen und in der Datenbank gespeichert.";
} else {
echo "Fehler beim Hochladen der Zusammenfassung.";
}
$stmt->close();
$conn->close();
}
?>
2
Answers
Your code uses incorrect data type binding for
LONGBLOB
. The correct type to use is "s" for string when binding binary data.You only really need to use the
b
/blob bind in mysqli if the row data you’re sending is, in aggregate, larger than your mysql server’s configuredmax_allowed_packet
. When using this bind type you must set the value tonull
and then usemysqli_stmt::send_long_data()
like so:The above example is lifted from the linked doc, but the key points are to bind a null variable, use a chunk size smaller than the configured
max_allowed_packet
[8192 in this example], and callsend_long_data()
as many times as necessary to power through the data.If you are certain that your data will always be smaller than
max_allowed_packet
then the much simpler answer is to use ans
/string bind as suggested by @suchislife.