PHP – Dateiupload als Blob Feld in MySQL speichern

In diesem Tutorial schauen wir uns an, wie wir ein Dateiupload Feld in einer MySQL-Datenbank abspeichern können. Ein Bild soll in einem Blob-Feld gesichert werden und bei Bedarf wieder ausgelesen und angezeigt werden.

Das gesamte Beispielscript gibt es am Ende zum Download. Grundsätzlich kann man argumentieren, ob Binärdaten überhaupt in eine Datenbank gespeichert werden sollten. Eine weitere Vorgehensweise wäre, die Dateien einfach im Dateisystem abzulegen und nur den Verweis in die Datenbank zu packen.

Das Uploadformular

Im ersten Schritt schauen wir uns das Uploadformular (erstellt mit dem DA-FormMaker) an:

Ein einfaches Formular für den Upload von einer Datei.

Die Datenbank

Zur Speicherung in der Datenbank legen wir folgende Tabelle an:

Auch diese ist recht einfach gehalten und besteht nur aus einer ID und dem Blob-Feld für die Bilddaten.

PHP-Code für den Upload

Das Formular verarbeiten wir mit einem PHP-Script:

if (!empty($_FILES['upload']['name']))
{
  $localFileName = 'uploads/' . $_FILES['upload']['name'];
  if (move_uploaded_file($_FILES['upload']['tmp_name'], $localFileName))
  {
    //Datei einlesen
    $content = file_get_contents($localFileName);

    //Verbindung zur MySQL-Datenbank
    $conn = new mysqli("localhost", "root", "", "test");

    //Verbindung überprüfen
    if ($conn->connect_error) 
    {
      die("Verbindung fehlgeschlagen: " . $conn->connect_error);
    }
    
    $sql = "INSERT INTO fileupload (image) VALUES (0x" .  bin2hex($content) . ")";
    
    //Einfügen in Datenbank
    if ($conn->query($sql) === TRUE) 
    {
      echo "Bild angelegt ID = " . $conn->insert_id;      
    } else 
    {
      echo "Fehler: " . $sql . "<br>" . $conn->error;
      die();
    }

	unlink($localFileName);
    $conn->close();
  }
} else 
{
  echo '<b>kein Upload!</b>';
}

Was passiert hier? Zuerst schauen wir, ob eine Datei hochgeladen worden ist. Anschließend wird die Datei in den Unterordner “uploads” verschoben. Anschließend lesen wir die Datei in eine Variable ein.

Nun bauen wir die Verbindung zur MySQL-Datenbank auf und fügen die Bilddaten in die Datenbank ein. Die Binärdaten des Bildes wandeln wir vorher mit der Funktion “bin2hex” vom binären Format in ein hexadezimales Format um.

Anschließend geben wir die ID des neuen Eintrags aus. In phpMyAdmin können wir nach dem Upload die Daten sehen:

Ausgabe des Bildes über PHP

Natürlich wollen wir auch wieder in die Daten herankommen. Dazu ein einfaches Beispiel, welches das Bild einfach im Browser ausgibt.

Der Code:

if (!isset($_GET["id"])) die("... keine ID angegeben.");

$id = $_GET["id"];
//Verbindung zur MySQL-Datenbank
$conn = new mysqli("localhost", "root", "", "test");

//Verbindung überprüfen
if ($conn->connect_error) 
{
  die("Verbindung fehlgeschlagen: " . $conn->connect_error);
}

$sql = "SELECT id, image from fileupload WHERE id = " . $id;
$result = $conn->query($sql);

if ($result->num_rows > 0) 
{
    while($row = $result->fetch_assoc()) 
    {
        $imgContent = $row["image"];
        $type = 'image/jpeg';
        header('Content-Type:'.$type);
        $size = strlen($imgContent);
        header('Content-Length: ' . $size);
        echo $imgContent;
    }
}

Dem Script übergeben wir die ID des Bildes. Sofern diese vorhanden ist, lesen wir die Zeile aus der Datenbank und geben das Bild dann aus. Wie wir hier sehen, muss es sich bei dem Bild um ein Jpeg-Bild handeln.

Das Bild wird anschließend einfach ausgegeben.

Download des Beispiels

2 Kommentare

  1. Moin,
    ich arbeite mit dem DA-FormMaker, in Verbindung mit der Erweiterung save_to_db.
    Gibt es eine Möglichkeit, das man das save_to_db Skript mit der Bilder upload Funktion erweitert?

    1. Ja klar das geht. Du verwendest einfach den Code wie hier und fügst den entsprechend hinzu. Du kannst dann entweder das Insert-Statement erweitern oder dir die ID zurückgeben lassen und dann für das Bild einen Update-Befehl machen.

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert