Werbung einblenden Werbung ausblenden


Home / Tutorials / mysql Handbuch / Bilder in einer Datenbank abspeichern


Überschrift
Ein Bild mit Perl abspeichern und anzeigen
Ein Bild mit PHP abspeichern und anzeigen

Überschrift

Die meisten Anwendungen, die den Upload eines Bildes ermöglichen Auktionen, Shops, Gästebücher, Foren, Chats, Anzeigenmärkte etc. speichern das Bild nicht direkt in der Datenbank. Sie speichern es in irgendeinem Ordner und speichern in der Datenbank selbst den Pfad zu dem Bild. Das ist machbar, aber unter Umständen umständlich. Umständlich ist es, weil dann die Verwaltung der Bilder mit "der Hand" programmiert werden muss. Das heisst, wird ein Bild gelöscht, muss der Verweis in der Datenbank gelöscht werden und das Bild selber. Wird ein Bild ersetzt, muss das neue Bild in die Datenbank eingetragen werden, der neue Link muss gesetzt werden und das alte Bild muss gelöscht werden (sowohl der Link auf das alte Bild als auch das Bild selber.) Das wiederum setzt dann voraus, dass man sich den Namen des alten Bildes erstmal aus der Datenbank fischt und das Bild dann löscht. Weiter ist es noch möglich, dass mehrere Leute Bilder mit dem gleichen Namen hochladen, man muss also auch noch dafür Sorge tragen, dass alle Bilder anders heissen. Alles etwas umständlich. Einfacher wäre es, das Bild direkt abzuspeichern, dann könnte man die ganze Administration allein durch SQL durchführen. Allerdings hat dieses Verfahren auch Nachteile. Die Datenbank wird dadurch langsamer.

Ein Bild mit Perl abspeichern und anzeigen


Ohne eine Programmiersprache geht es wohl nicht, da die Bilder ja erstmal von der Platte gekratzt werden müssen. Im übrigen will man das Bild ja anschliessend sehen, folglich braucht man eine Anwendung, die Bilder auch darstellen kann, z.B. einen Browser. Damit wir unser Bild in eine Tabelle einspeisen können, brauchen wir erstmal eine Tabelle. Diese generieren wir uns.

mysql> create table bilderli (
-> Ident int(5) NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> Name char(50),
-> Bild BLOB);
Query OK, 0 rows affected (0.16 sec)

mysql>

Will man größer Bilder einspeisen, wählt man anstatt Blob (64 kb) Mediumblob (16 MB). Anschliessend brauchen wir noch eine HTML Seite, die es uns erlaubt, die Bilder einzuspeisen, das heisst, sie auf den Fremdrechner upzuloaden und in die mysql Tabelle einzulesen (in die Spalte Bild).

Die HTML Seite (upload.htm)

<html>
<head>
<title> Bild upload direkt aus dem Browser </title>
</head>
<form action=http://127.0.0.1/cgi-bin/upload.pl enctype=multipart/form-data method=post>
<input type=hidden name=modul value=1>
Wählen Sie eine Datei
<input type=file name=datei> <br>
<input type=submit value=hochladen>
</form> <br><br>
Bild zeigen<br>
<form action=http://127.0.0.1/cgi-bin/upload.pl>
<input type=hidden name=modul value=2>
Nummer des Bildes <input type=text name=nummer><br>
<input type=submit value="Bild anzeigen">
</form>
</body>

Der eigentliche Perl Skript sieht so aus (upload.pl)

use CGI qw/:standard/;
use DBI;

$verbinden1="DBI:mysql:testlauf";
$verbinden2="";
$verbinden3="";
$dbh = DBI->connect( "$verbinden1","$verbinden2","$verbinden3") || die "Database connection not made: $DBI::errstr";
$ident=param('nummer');
$modul=param('modul');
$nummer=param('nummer');

if($modul eq 1)
{
$bild=param('datei');

while(<$bild>)
{
$bildle.=$_;
}

$sql = qq{insert into Bilderli (Name,Bild) values (?,?)};
$sth = $dbh->prepare( $sql );
$sth->execute($bild,$bildle);
$sth->finish();

$sql = qq{select max(Ident) from bilderli};
$sth = $dbh->prepare( $sql );
$sth->execute();
$zahl=$sth->fetchrow_array;
$sth->finish();
print "Bild wurde upgeloaded. Nummer ist $zahl";
}
else
{
my $sql = qq{select * from bilderli where Ident='$nummer'};
my $sth = $dbh->prepare( $sql );
$sth->execute();

while(@ergebnis=$sth->fetchrow_array)
{
print "$ergebnis[2]";
}
$sth->finish();

}

if($modul eq 3)
{
my $sql = qq{select * from bilderli where ident=$nummer};
my $sth = $dbh->prepare( $sql );
$sth->execute();
while(@ergebnis=$sth->fetchrow_array)
{
print $ergebnis[2];
}
$sth->finish();
}

$dbh->disconnect();


Dieser Skript hat also drei Bereiche, die jeweils in einer if Bedingung gekapselt sind. Der erste Teil wird nur ausgeführt, wenn, der User in der HTML Seite ein Bild uploadet, also auf den Knopf "hochladen" drückt. Damit der User sieht, welche Nummer der Datensatz hat, den er hochgeladen hat, ermitteln wir mit


select max(Ident) from bilderli

diese Nummer und blenden sie dem User nach erfolgtem Upload wieder auf. Ansonsten speichern wir das Bild so ab, wie wir das gewohnt sind. Für Details siehe mysql mit Perl ansteuern. Im zweiten Teil, dem von if ($modul=2) umschlossenen, können wir uns anhand der Nummer, dem Ident, der via auto_increment automatisch hochgezählt wird, einen bestimmtes Bild aus der Datenbank fischen. Interessanter ist es aber, eine Lösung zu zeigen, die es uns ermöglicht, alle Bilder eingebettet in HTML aufzublenden. Dies machen wir mit diesem Skript.

Perl Skript zum Auslesen aller Bilder (alle_zeigen.pl)

use DBI;
use CGI qw/:standard/;


$verbinden1="DBI:mysql:testlauf";
$verbinden2="";
$verbinden3="";
$dbh = DBI->connect( "$verbinden1","$verbinden2","$verbinden3") || die "Database connection not made: $DBI::errstr";
$ident=param('nummer');
$modul=param('modul');
$nummer=param('nummer');

print "<html><head><title>Alle Bilder zeigen</title></head><body bgcolor=blue><table>";

my $sql = qq{select Ident from bilderli};
my $sth = $dbh->prepare( $sql );
$sth->execute();

while(@ergebnis=$sth->fetchrow_array)
{
print "<tr><td><img src=http://127.0.0.1/cgi-bin/upload.pl?modul=3&nummer=$ergebnis[0]></td></tr>";
}
$sth->finish();
print "</table></body></html></head>";

$dbh->disconnect();

Dieser Skript sollte im selben Ordner liegen, in dem auch der Skript upload.pl liegt. Hier erhält der image Tag nicht, wie gewohnt, den virtuellen Pfad zu einem Skript, sondern den virtuellen Pfad zu upload.pl. Der Query String modul=3 sorgt dafür, dass er den dritten Teil von upload.pl ansteuert. Wir durchlaufen also alle Datensätze der Tabelle bilderli im Ordner testlauf und fischen uns jeweils die Nummer raus. Diese Nummer übergeben wir an upload.pl. Dieser wiederum gibt dann das Bild zurück.

Ein Bild mit PHP abspeichern und anzeigen

Hier PHP verhält es sich ähnlich. Erstmal richten wir wieder die Tabelle ein.

mysql> create table bilderli (
-> Ident int(5) NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> Name char(50),
-> Bild BLOB);
Query OK, 0 rows affected (0.16 sec)

Dann brauchen wir wieder eine HTML Seite, von der aus wir den Skript starten.

Die HTML Seite (upload3.htm)

<html>
<head>
<title> Bild upload direkt aus dem Browser </title>
</head>
<form action=http://127.0.0.1/upload.php enctype=multipart/form-data method=post>
<input type=hidden name=modul value=1>
Wählen Sie eine Datei
<input type=file name=datei> <br>
<input type=submit value=hochladen>
</form> <br><br>
Bild zeigen<br>
<form action=http://127.0.0.1/upload.php>
<input type=hidden name=modul value=2>
Nummer des Bildes <input type=text name=nummer><br>
<input type=submit value="Bild anzeigen">
</form><br>
<A href=upload3.php>Alle Bilder zeigen</a>
</form>
</body>

Der eigentliche Skript, der das Bild in die mysql Datenbank einspeist und einzelne Bilder wieder rausholt sieht dann so aus.

Der PHP Skript, der die Bilder einspeist (upload.php)

<?
mysql_connect("localhost","","");
mysql_select_db("testlauf");

if($modul ==1)
{
print "<html><head><title>Bild in eine mysql Datenbank einspeisen mit PHP</title></head>
<body>";
$bild=addslashes(fread(fopen($datei, "r"), filesize($datei)));
$Name=$HTTP_POST_FILES['datei']['name'];
mysql_query("insert into bilderli(Name,bild) values ('$Name','$bild')");
$zahl= mysql_insert_id();
echo "Der Name des Files ist ".$HTTP_POST_FILES['datei']['name']."<br>";
echo "Der Grösse des Files ist ".$HTTP_POST_FILES['datei']['size']."<br>";
echo "Der File ist vom Typ: ".$HTTP_POST_FILES['datei']['type']."<br>";
echo "Der Name des Files ist ".$HTTP_POST_FILES['datei']['name']."<br>";
$dateiname=$HTTP_POST_FILES['datei']['name'];
echo "Der File wurde upgeloaded. Die Nummer des Bildes ist $zahl";
print "</body></html>";
}

if($modul ==2)
{
$zeiger=mysql_query("select bild from bilderli where Ident=$nummer");
$ergebnis=mysql_fetch_array($zeiger);
print $ergebnis['bild'];
}

if($modul ==3)
{
$zeiger=mysql_query("select bild from bilderli where Ident=$nummer");
while($ergebnis=mysql_fetch_array($zeiger))
{
print $ergebnis['bild'];
}
}
mysql_close();
?>

Der Aufbau ist dem Aufbau in Perl identisch. Wundern kann man sich höchstens über diese Zeile.

$bild=addslashes(fread(fopen($datei, "r"), filesize($datei)));

Mit fopen öffnen wir die Datei zum lesen (r), die geöffnete Datei lesen wir in voller Länge, filesize($datei), mit dem Befehl fread aus um schliesslich endlich mit addslashes werden einfache Anführungsstriche ' , doppelte Anführungsstriche ", Leerzeichen und der Backslash \ in Anführungsstriche gesetzt. Dies scheint für Datenbanken notwendig zu sein, auf jeden Fall funktionniert es nicht, wenn man es unterläßt. Schluss endlich brauchen wir noch einen Skript, der alle Bilder aufblendet und diese Bilder auch in eine HTML Seite integriert. Der sieht dann so aus. Er muss im selben Ordner liegen, wie der Skript upload.php.

Skript der alle Bilder anzeigt (upload3.php)

<html>
<head>
<title> Bild upload direkt aus dem Browser </title>
</head>
<form action=http://127.0.0.1/upload.php enctype=multipart/form-data method=post>
<input type=hidden name=modul value=1>
Wählen Sie eine Datei
<input type=file name=datei> <br>
<input type=submit value=hochladen>
</form> <br><br>
Bild zeigen<br>
<form action=http://127.0.0.1/upload.php>
<input type=hidden name=modul value=2>
Nummer des Bildes <input type=text name=nummer><br>
<input type=submit value="Bild anzeigen">
</form><br>
<A href=upload3.php>Alle Bilder zeigen</a>
</form>
</body>

vorhergehendes Kapitel