Antworten auf deine Fragen:
Neues Thema erstellen

[PHP u. MySQL] Bild Upload mit Beschreibung: Bilder werden nicht gespeichert.

B

b3rklar

Guest

Schönen guten Tag zusammen :).

Nach mehreren Tagen hin und her gegoogle und Videos schauen bei YouTube bin ich mit meinem Latein am Ende :confused:.

Ich versuche, ein Bild-Upload mit Beschreibung zu realisieren und der Beschreibungstext wird auch eins a übernommen und in die Datenbank eingetragen, aber das Bild leider nicht.

Ich habe über Google und co. einige Lösungswege gefunden, aber irgendwie will das alles nicht so, wie ich es will :D.
Der Ordner "images" hat die Berechtigung "777" um den Fehler auszuschliessen. Ich bin bei dem Anbieter 1und1 (falls das jemanden hilft).

Folgende Sachen haben ich schon ausprobiert im php Bereich...


//.PHP
<?php
$db = mysqli_connect("xxxx", "xxxxxx", "xxxxxx", "xxxxx");
$msg = "";

if (isset($_POST['upload'])) {
$target = "images/".basename($_FILES['image']['name']); // 1. Versuch
$target = $_SERVER['DOCUMENT_ROOT']."/images/".basename($_FILES['image']['name']); // 2. Versuch
$target = "".basename($_FILES['image']['name']); // 3. Versuch


$image = $_FILES['image']['name'];
$image_text = mysqli_real_escape_string($db, $_POST['image_text']);


$sql = "INSERT INTO images (image, image_text) VALUES ('$image', '$image_text')";
mysqli_query($db, $sql);

if (move_uploaded_file($_FILES['image']['tmp_name'], $target)) {
$msg = "Bild wurde hochgeladen";
}else{
$msg = "Problem beim hochladen";
}
}

$result = mysqli_query($db, "SELECT * FROM images");

?>




Im html Bereich schaut es wie folgt aus...

//.HTML

<div id="content">
<?php

while ($row = mysqli_fetch_array($result)) {
echo "<div id='img_div'>";
echo "<img src='images/".$row['image']."' >";
echo "<p>".$row['image_text']."</p>";
echo "</div>";
}
?>

<form method="POST" action="bilder.php" enctype="multipart/form-data">
<input type="hidden" name="size" value="1000000">
<div>
<input type="file" name="image">
</div>
<div>
<textarea id="text" cols="40" rows="4" name="image_text" placeholder="Beschreibe das Bild..."></textarea>
</div>
<div>
<button type="submit" name="upload">Hochladen</button>
</div>
</form>
</div>





//.DB

Das sind die folgenden Einstellungen die ich in der Datenbank erstellt habe.

Tabellenname: images
Spalte 1: id int(11) AUTO_INCREMENT
Spalte 2: image varchar(200)
Spalte 3: image_text text


lg
René :)

PS: Ich freue mich auf eure Vorschläge

// Folgenden Beitrag habe ich auch schon gelesen https://www.psd-tutorials.de/forum/...-bildnamen-in-datenbank-speichern-wie.136603/
 

G

Gelöschtes Mitglied 633957

Guest

Erst einmal willkommen im Forum!

Wenn ich es richtig verstehe, sollen Bild und Beschreibung in die Datenbank und an anderer Stelle wieder ausgegeben werden.
Da bist Du in der richtigen Richtung unterwegs und doch ein wenig vom Weg abgekommen.
Ich probiere mal etwas aus und melde mich dann wieder!
 
B

b3rklar

Guest

Erst einmal willkommen im Forum!

Wenn ich es richtig verstehe, sollen Bild und Beschreibung in die Datenbank und an anderer Stelle wieder ausgegeben werden.
Da bist Du in der richtigen Richtung unterwegs und doch ein wenig vom Weg abgekommen.
Ich probiere mal etwas aus und melde mich dann wieder!


Moin tynick.

Ja, genau das habe ich vor :)

Ich Danke dir für die Meldung und es ist schön zuhören, dass ich nicht ganz falsch liege mit meinem Weg ^^.
 
G

Gelöschtes Mitglied 633957

Guest

Ja, genau das habe ich vor :)
Dann sollst Du auch endlich meinen Lösungsansatz bekommen! Bei Deiner Lösung sind die Ideen zur Speicherung in der Datenbank und in einem Verzeichnis ein wenig "verkuddelmuddelt"!

Ich habe zuerst eine Datenbank "bilder" erstellt und dann eine Tabelle "hochgeladen", mit folgendem Inhalt:

Beachte, dass die Spalte "bild" vom Typ LONGBLOB ist; hier werden die Bilddaten gespeichert!

Ich habe mich entschieden, für Upload und Anzeige zwei Dokumente anzulegen - man könnte die PHP-Dateien aber auch zusammenfassen.

Mein Upload-Dokument "upload.php" schaut wie folgt aus...
Ich habe mich bemüht einigermaßen sinnvoll zu kommentieren:
PHP:
<?php
// Verbindung zur Datenbank (host/server, benutzer, passwort, datenbankname)
$mysqli = new mysqli("localhost", "root", "password", "bilder");

// Fehlermeldung bei Verbindungsproblemen
if ($mysqli->connect_errno) {
    printf("Verbindung fehlgeschlagen: %s\n", $mysqli->connect_error);
    exit();
}

// Wenn auf Senden-Button geklickt wird...
if(isset($_POST["senden"])) {
// Püfen ob die Beschreibung nicht leer ist
if(!empty($_POST["beschreibung"])) {
// Dateiinformationen holen (temporärer Name, Dateiname, -größe und -typ)
  $tempname = addslashes(file_get_contents($_FILES['bild']['tmp_name']));
  $bildname = addslashes($_FILES['bild']['name']);
// Größe und Typ wollte ich noch für eine Prüfung verwenden, habe es dann aber sein lassen - könnte aber noch interessant werden für die Verwendung des Scripts mit einem Hostingpaket
  $bildgroesse = addslashes($_FILES['bild']['size']);
  $bildtyp = addslashes($_FILES['bild']['type']);

// Prüfen ob ein Dateiname existiert
  if(!empty($bildname)) {
// Prüfen ob Dateiname nur aus Buchstaben, Ziffern und -_. besteht
    if (preg_match('/^[-a-zA-Z0-9_.]+$/', $bildname)) {

// Erlaubte Dateiendungen
      $erlaubt = array('jpg','jpeg');
// Dateiendung aus Dateiname
      $endung = pathinfo($bildname, PATHINFO_EXTENSION);

// Prüfen ob Dateiendung zu den erlaubten Endungen passt
      if(in_array($endung, $erlaubt)) {
// HTML, XML und PHP Tags aus Beschreibung entfernen
        $beschreibung = strip_tags($_POST["beschreibung"]);
// Info in Datenbank, in Tabelle "hochgeladen" eintragen
        $eintragen = "INSERT INTO hochgeladen (bild, name, beschreibung) VALUES ('$tempname', '$bildname', '$beschreibung')";
          if ($mysqli->query($eintragen) === TRUE) {
            $meldung = "<B>Vielen Dank!</B> Es wurde ein neuer Datensatz hinzugef&uuml;gt!";
          } else {
           $meldung = "Fehler: " . $eintragen . "<BR />" . $mysqli->error;
          }
      } else {
        $meldung = "<B>Fehler</B>: Das ausgew&auml;hlte Bild hat eine unerlaubte Dateiendung!";
      }
    } else {
      $meldung = "<B>Fehler</B>: Bitte verwenden Sie einen Dateinamen, der nur aus Buchstaben, Ziffern und den Zeichen _ - . besteht!";
    }
  } else {
    $meldung = "<B>Fehler</B>: Sie haben keine Datei ausgew&auml;hlt!";
  }
} else {
  $meldung = "<B>Fehler</B>: Sie m&uuml;ssen eine Beschreibung des Bildes einf&uuml;gen!";
}
} else {
  $meldung = "Bitte w&auml;hlen Sie Ihr Bild aus, geben Sie eine Beschreibung ein und klicken Sie auf &quot;Bild hochladen&quot;!";
}

// Verbindung zur Datenbank trennen
$mysqli->close();
?>

<!doctype html>
<html lang="de">

<head>
   <meta charset="UTF-8" />
   <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
   <title>MySQL Bilder Upload</title>
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>

<body>

<form action="" method="post" enctype="multipart/form-data">
<p><B>Bild ausw&auml;hlen und hochladen...</B></p>
<BR />
<p><input name="bild" type="file" /></p>
<p><textarea name="beschreibung" rows="4" cols="50" maxlength="200" placeholder="Beschreibe das Bild mit maximal 200 Zeichen..."></textarea></p>
<p><input name="senden" type="submit" value="Bild hochladen" /></p>
</form>
<BR />
<small style="color:red;">
<?php
// Meldung ausgeben
echo $meldung;
?>
</small>
<BR /><BR />
Hier geht es zur <a href="./galerie.php" target="_self">Bildergalerie</a>

</body>
</html>
Die Ausgabe der "upload.php" schaut dann so aus:


Die mit Daten gefüllte Tabelle, sollte dann so ausschauen:


Angezeigt wird das ganze mit der "galerie.php":
PHP:
<!doctype html>
<html lang="de">

<head>
   <meta charset="UTF-8" />
   <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
   <title>MySQL Bilder Ausgabe</title>
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>

<body>

<B>BILDERGALERIE</B>
<BR /><BR />

<?php
// Verbindung zur Datenbank (host/server, benutzer, passwort, datenbankname)
$mysqli = new mysqli("localhost", "root", "password", "bilder");

// Fehlermeldung bei Verbindungsproblemen
if ($mysqli->connect_errno) {
    printf("Verbindung fehlgeschlagen: %s\n", $mysqli->connect_error);
    exit();
}

// Alle Inhalte aus der Tabelle holen
$inhalte = "SELECT * FROM hochgeladen";
if ($inhalt = $mysqli->query($inhalte)) {

// Inhalte aufdröseln, Schleife durchlaufen, mögliche HTML, XML oder PHP Tags aus Beschreibung und Bildname entfernen
  while ($spalte = $inhalt->fetch_assoc()) {
    $bildinhalt = $spalte['bild'];
    $bildinfo = strip_tags($spalte['beschreibung']);
    $bildname = strip_tags($spalte['name']);

// Bilder mit Info (Beschreibung, Dateiname) ausgeben
    echo '<div style="float:left; width:260px;"><img src="data:image/jpeg;base64,'.base64_encode($bildinhalt).'" width="250" /><BR />';
    echo $bildinfo.'<BR /><small>('.$bildname.')</small><BR /><BR />';
    echo '</div>';
  }
}

// Verbindung zur Datenbank trennen
$mysqli->close();
?>

<div style="clear:left;"></div>
<BR /><BR />
Hier geht es zum <a href="./upload.php" target="_self">Bilder-Upload</a>

</body>
</html>
Die dann z.B. so ausschaut:


So viel Code widerspricht ein wenig dem Grundgedanken des Forums: "Hilfe zur Selbsthilfe", jedoch bietet er viele Möglichkeiten daran zu arbeiten:
  • die Ausgaben sollten schon hübscher daherkommen
  • es lässt sich noch einiges an Funktionalität einbauen (z.B. das Löschen von Bildern aus der Datenbank)
  • und in puncto Sicherheit sollten sich auch noch einige Gedanken gemacht werden
Dieser Code bietet nur einen minimalen Schutz vor Bösewichten, die Deinem Server oder der Datenbank Übles wollen!

Ich hoffe Du kannst damit etwas anfangen und baust dann etwas eigenes und viel besseres!

Noch der Hinweis an alle die mehr Ahnung von PHP und MySQL haben:
Bitte anmerken wenn ich Käse zusammengeschrieben habe!

Edit: Rechtschreibung
 
Zuletzt bearbeitet von einem Moderator:
B

b3rklar

Guest

Moin moin tynick. :)

Ich danke dir, für deine Hammer Arbeit und das Du mir so schnell geholfen hast. :danke:

Die Lösung werde ich morgen oder auch noch heute Abend ausprobieren
(bis zum Football Spiel um 02:30 Uhr ist es ja noch hin):grin:.
Das mit den Sicherheitslücken habe ich im Blick und natürlich,
wirst Du von mir nach der Umsetzung ein Feedback bekommen :innocent:.


lg
René
 

Curanai

Aktives Mitglied

Hallo zusammen, zum oben vorgelegten Quellcode mag ich nichts sagen. Aber ich gebe einen Denkanstoß in puncto "Konzeptfehler", da ich diese Ansicht vertrete ...

1. Bilder sind Dateien und gehören damit ins Dateisystem.
2. Die Datenbank zu konsultieren, um ein Bild daraus zu laden, ist ein Performance-Killer mit unnötigem Overhead am Gesamtsystem. Bei ein paar kleinen Bilddateien auf Schlag ist es u. U. am Ende egal; eine Bild-Gallerie hingegen lässt die Datenbank im Umfang exorbitant an die Decke gehen.
3. Bei großen Bildern gibt es eine gesteigerte Absturzgefahr für die komplette Datenbank (nämlich bei in- wie output).
4. Ein Backup der Datenbank ist ohne Bildanteil deutlich geringer (Größe) und performanter (Dauer) erstellt. Die Gefahr von Timeouts bei bspw. "on-the-fly"-Backups ergibt sich damit nicht.

Ja, am Anfang ist alles rappelschnell. Designfehler an der Datenbank zeigen sich später und wenn Du dann Bilder vom letzten Urlaub drin hast (10.000?) merkt man es ganz, ganz schnell. Die Quittung bekommst Du dann an unerwarteter Stelle, sofern die Seite öffentlich ist.

Entschuldigt also die Störung, aber das Problem liegt für mein Empfinden bereits vor dem Quellcode – nämlich beim Konzept.

Wie immer gilt: Viel Spaß bei der Umsetzung!

Beste Grüße
 

Dagobert68

Nicht mehr ganz neu hier

Moin :)

Stimme @Curanai voll und ganz zu. Die Bilder unbedingt im Dateisystem ablegen und in der Datenbank dann nur den Dateinamen speichern.

Ich bin bei meiner selbstgestrickten Bilddatenbank sogar so weit gegangen, dass ich die Bilder direkt in einem entsprechenden Bildbearbeitungsprogramm (in meinem Fall Lightroom) mit IPTC-Stichwörtern und einer IPTC-Beschreibung versehen habe.

So lade ich nun die Bilder per FTP in ein Upload-Verzeichnis auf dem Webserver, rufe dann in meinem zu diesem Zweck erstellten Admin-Bereich eine Seite auf mit einer PHP-Programmierung, die die Bilder in diesem Upload-Verzeichnis ausliest mitsamt EXIF- und IPTC-Daten, diese in die Datenbank schreibt, außerdem noch Thumbnails erstellt und die Bilder dann passend zur jeweiligen Galerie im Dateisystem ablegt. Den ursprünglichen Dateinamen wollte ich mir auch gerne erhalten, so dass ich lediglich beim Kopieren in das endgültige Verzeichnis noch die Datensatz-ID vor den Dateinamen packe, um Dopplungen und unbeabsichtigtes Überschreiben von vornherein zu vermeiden.
Anschließend lösche ich die hochgeladenen Bilder im Upload-Verzeichnis wieder (natürlich mit Prüfung, ob erfolgreich kopiert etc.).

Der Vorteil der Verschlagwortung und Beschreibung in den IPTC-Daten ist meiner Ansicht nach, dass diese Daten fest an die Bilder gekoppelt sind. Falls du deine Bilder mal in einer anderen Datenbank / einem anderen System präsentieren möchtest, gehen die in deiner alten Datenbank vorhandenen Beschreibungen / Stichwörter nicht verloren oder müssen auch nicht umständlich exportiert und wieder den Bildern zugeordnet werden. Ich spreche aus Erfahrung. Meine erste Bilddatenbank hatte die Beschreibungen auch nur in der Datenbank, so dass ich im zweiten Anlauf alles neu zuordnen durfte und zu dem Entschluss kam, dass ich genau das nie wieder tun möchte :neee:

Das nur ergänzend als Überlegung dazu.

Viel Erfolg und liebe Grüße,
Tina
 
G

Gelöschtes Mitglied 633957

Guest

Entschuldigt also die Störung
Da gibt es nichts zu entschuldigen, es ist ja ein durchaus sinnvoller Einwand. Nicht ganz ohne Grund habe ich nachgefragt, ob die Beschreibung und das Bild in die Datenbank sollen.
Es kommt natürlich stark auf den Verwendungsweck an, ob das Laden des Bildes in eine Datenbank so Sinn ergibt. Die Galerie kam ja von mir um auch die Ausgabe zu zeigen und insgesamt, vornehmlich darum einen Weg aufzuzeigen wie es gehen könnte.
Vielleicht wird die Datenbank ja benutzt um Problemen aus dem Weg zu gehen die möglicherweise beim Upload via HTTP ins Dateisystem mit dem gewählten Hostingpaket entstanden sind - vielleicht als Zwischenschritt um eine interne Sichtprüfung durchzuführen und die Dateien dann für die öffentliche Verwendung, aus der Datenbank ins Dateisystem zu bringen.... Wer weiß?

In jedem Fall ist Dein Einwand richtig und für den TE bestimmt nicht uninteressant!
 

Curanai

Aktives Mitglied

Da gibt es nichts zu entschuldigen, ...
Also im ersten Moment bin ich zusammengezuckt. :D

Vielleicht wird die Datenbank ja benutzt um Problemen aus dem Weg zu gehen die möglicherweise beim Upload via HTTP ins Dateisystem mit dem gewählten Hostingpaket entstanden sind...
Hier gibt es typischer Weise immer nur zwei Problemzonen (egal in welches Forum man schaut): Limit der Dateigröße beim File-Upload (weil vorher abgebrochen wird oder zugehöriger Timeout) oder Fehler bei der Umsetzung, da ein finales move_uploaded_file() schlecht gemacht ist und man nicht versteht, was man da eigentlich macht und ein Pfad (auch im Hosting-Paket) nicht damit anfängt, was in Deinem FTP-Programm oben steht.

... vielleicht als Zwischenschritt um eine interne Sichtprüfung durchzuführen und die Dateien dann für die öffentliche Verwendung, aus der Datenbank ins Dateisystem zu bringen
Das wäre ebenfalls - IMO - eine falsche Anwendung. Denn: Bilder zur Abnahme liegen für Redakteure oder Admins in einem ganz anderen, für User nicht erreichbaren Unterordner (!). Hier hilft nur das Backend, um da ran zu kommen! Erinnern wir uns kurz an div. Editoren in CMS-Kisten wie Joomla oder WordPress, die eine beliebige Bild-Datei in den öffentlichen temp-Folder platziert haben (den man von außen erreicht). Ein Schelm, wer da als Gast Bilder hochladen konnte. Ach nee ... waren dann auch eher Web-Shells als Bilder getarnt.

Kurzum: Das Zurückhalten von User-Uploads und eine Freigabe – da bin ich total bei Dir. Aber auch da hat die Datenbank nicht das Bild, sondern nur einen eindeutigen Bildbezeichner, einen Status, von wem es kommt, wann es kam, wie es vorher hieß und dann der angedachte Zielort (wenn variiert, user-bedingt, privater Bereich ... sowas!). Und um die Datenbank performant zu halten, wird der Eintrag daraus später in ein Log-File übernommen (ob freigegen oder verworfen), während das Bild an den Zielort verschoben und der Datenbankeintrag selbst gelöscht wird. Den User informieren ... soll man auch immer. :D

In jedem Fall ist Dein Einwand richtig und für den TE bestimmt nicht uninteressant!
Danke (gilt auch für die vorige Zustimmung von @Dagobert68).
 

msa1989

Bin da

Pauschal zu sagen Bilder gehören nicht in die Datenbank halte ich für Grundlegend falsch.

Eine vollständige Trennung von Webapplikation und der Datenhaltungsschicht ist wesentlich einfacher wenn ich einfach alles in der Datenbank speichere. Mein Quellcode steht damit vollständig unabhängig von den Daten. Moderne Datenbanksysteme haben auch überhaupt kein Problem damit 500GB oder größer zu sein. Nicht die Größe der DB macht den Unterschied sondern ob das DB Modell anständig normalisiert ist. Aus eigener Erfahrung kann ich sagen dass sowohl MS SQL, PostgreSQL und MySQL sehr sehr gut skalieren. Ich denke dasselbe gilt auch für weitere DB Systeme.
Ich persönlich habe lieber den gesamten Quellcode im GIT von wo aus ich die Applikation erstelle und sichere nur eine Datenbank.

Edit:
Was ich vergessen habe zu erwähnen:
Im Falle der Bildergalerie macht es selbstverständlich Sinn die Bilder in einem lokalen Applikationscache zu haben und von dort aus auszuliefern. Hier muss ich den Vorrednern natürlich recht geben, dass sowohl speichern als auch lesen von der DB unnötig Ressourcen kostet. Ich würde das so machen, dass die Bilder in der DB beim hochladen gesichert werden und beim ersten Zugriff in den Cache geladen werden.
 
B

b3rklar

Guest

Moin moin zusammen, ich danke euch allen für die anregenden Worte :).
Das mit den Bilden in der DB war und ist noch zurzeit für Testzwecke und
die Bilder in ein eigenem Verzeichnis unterzubringen sehe ich auch ein.

Es ist verdammt cool, dass sich so viele bereit erklärt haben ihr Wissen mit mir zu teilen.

LG
René
 

Curanai

Aktives Mitglied

Pauschal zu sagen Bilder gehören nicht in die Datenbank halte ich für Grundlegend falsch.
Bedenke bitte, dass nicht jedes Projekt verschiedenster Couleur ausnahmslos eine Gallerie hat. Der Schwerpunkt liegt daher meist ganz woanders. Da der TO dies aber nicht weiter erwähnt, kann es sich dabei um eine Seite handeln, die eine ganz andere Mission verfolgt (als nur Bilder zu zeigen). Doch ich schrieb ja bereits ...

Bei ein paar kleinen Bilddateien auf Schlag ist es u. U. am Ende egal ...

Eine schöne Idee wäre hingegen der Applikationscache – reden wir dann beide über ".appcache"? Denn der hat bekanntlich eine andere Nebenwirkung beim User: Ablegen der Bilder auf der Festplatte. Wenn Du HTTP Caching meinst, verweise ich auf den Hinweis fehlender Möglichkeiten für den kleinstmöglichen, hier lesenden Anwender (u. U. der TO sogar selbst). Technisch würde dieser das nicht in sein 2,99-EUR-Web-Hosting-Paket bekommen.

Aber wie immer gilt: "Viele Wege führen nach Rom." Es gibt nicht "die beste Lösung" - schon gar nicht für uns Außenstehende.

Starken Sonntag!
 
Bilder bitte hier hochladen und danach über das Bild-Icon (Direktlink vorher kopieren) platzieren.
Antworten auf deine Fragen:
Neues Thema erstellen

Willkommen auf PSD-Tutorials.de

In unseren Foren vernetzt du dich mit anderen Personen, um dich rund um die Themen Fotografie, Grafik, Gestaltung, Bildbearbeitung und 3D auszutauschen. Außerdem schalten wir für dich regelmäßig kostenlose Inhalte frei. Liebe Grüße senden dir die PSD-Gründer Stefan und Matthias Petri aus Waren an der Müritz. Hier erfährst du mehr über uns.

Stefan und Matthias Petri von PSD-Tutorials.de

Nächster neuer Gratisinhalt

03
Stunden
:
:
25
Minuten
:
:
19
Sekunden

Flatrate für Tutorials, Assets, Vorlagen

Zurzeit aktive Besucher

Statistik des Forums

Themen
118.611
Beiträge
1.538.342
Mitglieder
67.524
Neuestes Mitglied
BSKGA
Oben