Erklärungen zur Nutzung von Blob/Longblob mit Verzeichnissen

marcaurel

Mitglied
hey,

ich hab folgendes Problem. Und zwar möchte ich, dass mittels eines Formulars Bilder in eine SQL-Datenbank gespeichert und später dann auch abgerufen werden könne. Bei meiner Suche nach Informationen darüber habe ich gelesen, dass am besten die Bilder dann nicht direkt in der Datenbank, sondern in einem Verzeichnis gespeichert werden sollten. Im Blob/Longblob der Datenbank steht dann nur der Pfad zu diesem Verzeichnis.

Dazu wollte ich Euch mehrere Dinge fragen:

1. Wo ist dann hierbei der Unterschied zwischen Blob und Longblob. Ich habe gelesen dass bei Longblob größere Dateien gespeichert werden können, aber ist dies bei einer Speicherung von lediglich dem Pfad dann überhaupt notwendig?

2. Wenn man eine solche Homepage später online stellt, ist es nicht sicherer die Dateien direkt in der Datenbank zu speichern, als dass man ein Verzeichnis macht?

3. Wisst Ihr villeicht zufällig ein Toutorial oder eine Erklärung die Anfängergerecht erleutert, wie man soetwas überhaupt anlegt?
 
Hi

Bilder als normnale Dateien zu speichern hat einige Vorteile, ja. Aber...
Im Blob/Longblob der Datenbank steht dann nur der Pfad zu diesem Verzeichnis.
Warum dann überhaupt ein Blob? Der Pfad ist normaler Text, kein Blob nötig, und deswegen auch keine Probleme mit der Handhabung (Blobs sind nicht so einfach wie Zahlen oder Text, bezüglich Einfügen, Abfragen, Where-Klauseln usw.).

Wenn man eine solche Homepage später online stellt, ist es nicht sicherer die Dateien direkt in der Datenbank zu speichern, als dass man ein Verzeichnis macht?
Sicherer in welcher Hinsicht? Funktionalität (Raceconditions etc.), Backups, Zugriffskontrolle, Malware, ...?
 
:) danke für deine schnelle Antwort!

ich meinte im Bezug auf Malware, könnte dies ein Problem darstellen?

Das Bedeutet ich habe einfach in der Datenbanktabelle eine spalte mit z. b.: pfad, varchary 255 und dort wird dann der pfad eingespeichert? Weißt du vill zufällig ein Toutorial wo erklärt wird wie das gemacht wird? Denn zunächst müsste das Verzeichnis wo alle Bilder gespeichert werden erschaffen werden, dann es dadrin gespeichert werden (mit eindeutiger Festlegung des Dateinamens) und gleichzeitig dieser Pfad dann in die Datenbank gespeichert werden. Kennst du da zufällig eine ausführliche anfängerfreundliche Erklärung?
 
Das Bedeutet ich habe einfach in der Datenbanktabelle eine spalte mit z. b.: pfad, varchary 255 und dort wird dann der pfad eingespeichert?
Ja, zB. so. Aber, um noch weiter zu gehen, wenn es nur ums FInden der Bilder geht braucht man eigentlich überhaupt keinen textuellen Pfad.

Die Tabelle hat idealerweise eine ID-Spalte (Nummer, Autoincrement) und noch ggf. andere paar Zusatzspalten.
Beim Upload dann folgende grundlegenen Schritte:
a) Prüfen ob das Verzeichnis exisitert, und ggf. anlegen
b) Einen Tabelleneintrag anlegen, dabei die nächste freie ID eben mit dem Autoincrement von der DB entscheiden lassen.
c) Das Bild zu einem einheitlichen Format wie PNG konvertieren (hat zwei Gründe, die ich später erkläre)
d) Die Bilddatei in das Verzeichnis verschieben und so umbenennen, dass es die ID als Namen hat. Mit ID 1234 also 1234.png

Grund 1/2 für PNG: Man muss sich so in der DB nicht speichern, welche Endung der Dateinamen hat. (Man könnte auch einfach den Dateinamen 1234 ohne Endung nehmen, aber das Bild dann direkt in HTML-imgs zu verwenden wird der Browser nicht so gern haben). PNG verschlechtert die Qualität auch nicht. (vt. ein Problem ist, dass animierte Gifs nach dem Konvertieren nicht mehr animiert sind).
(Grund 2/2 später).

Wenn man sehr viele Bilder erwartet, kann es für die Zugriffszeiten im Dateisystem helfen, die Bilder in zB. Tausendergruppen in eigene Verzeichnisse zu geben. Also diebilder/1/1234.png statt diebilder/1234.png, diebilder/1234/12345678.png statt diebilder/12345678.png, diebilder/0/123.png statt diebilder/123.png. Praktisch die ID durch 1000 dividieren, um den Unterordnernamen zu erhalten. Die Verzeichnisse müssten durch das Programm eben auch bei Bedarf erst angelegt werden.

Eine anfängerfreundliche Erklärung zu genau dem Problem kenn ich nicht, aber für die 4 Schritte oben gibt es genug einzelne Erklärungen in Google.

Zur Sicherheit...

ich meinte im Bezug auf Malware, könnte dies ein Problem darstellen?
Nein.
Bzw. Ja, aber die zwei Möglichkeiten machen keinen Unterschied.

Die Hauptgründe, warum Malware heutzutage funktioniert:
a) Fehler in Programmen (egal ob dein PHP-Programm oder Apache oder das Betriebssystem oder...), die nicht ausgebessert wurden (zB. weil die "guten" Leute vom Fehler noch nichts wissen).
Fehler kann man immer machen, egal ob DB oder Datei.
b) irgendein Sicherheitsfeature wurde nicht eingebaut, weil der Programmierer keine Ahnung gehabt hat, dass diese Sache überhaupt zum Problem werden kann.

Für (b) gibt es hier zB. folgende Sachen:

1) Bilder, die von deinem PHP-Programm als Programm gestartet werden (mit include/require/eval/system/exec/...). Ich habe nie verstanden, warum man das überhaupt machen will, aber solche Fälle kommen wirklich vor. Der Angreifer muss dann nur eine Datei abc.jpg mit einem Programm statt Bild drin raufladen und ist praktisch fertig.
2) Mit zB. getimagesize in PHP untersuchen, ob es von PHP überhaupt als Bild erkannt wird. Sonst löschen.
3) Beim abspeichern nie den Dateinamen nehmen, den man vom Client bekommen hat. (Die ID und .png wie oben beschrieben löst das schon)
4) Um auch die letzten Reste von möglichem Code, versteckten Infos, Trackingzeug, usw. zu entfernen: Die Bilder nicht einfach so wie erhalten abspeichern, sondern zuerst einmal zu BMP konvertieren, und dann noch zu PNG, und das dann erst abspeichern (wirklich konvertieren, nicht nur den Dateinamen ändern). (Das ist Grund 2/2 für PNG).
5) Beim "Verschieben" des Bildes in das Bilderverzeichnis nicht verschieben, sondern nur den Dateiinhalt auslesen,, in eine neue Datei schreiben, und das Original dann löschen. Idealerweise während der BMP/PNG-Konvertierungen, da muss man es sowieso auslesen/neuschreiben. Grund sind verschiedene Metainfos von Dateien (Trackingzeug und Flags wie Executable)
6) Bilder, die mehr als soundso viel Byte haben, nicht annehmen.
7) Das $_FILES-Array in PHP hat pro Upload mehrere Einträge: tmp_name und error braucht man (der Dateiname wo es zurzeit am Server ist, und ob der Upload überhaupt funktioniert hat bzw. ob überhaupt etwas raufgeladen wurde). Alle anderen (name, type, size) einfach ganz ignorieren, kommt nämlich vom Client und könnte gefälscht sein. Name und Type bracuht man mit den ID-PNG-Regeln sowieso nicht, aber auch size (die Dateigröße in Byte) besser nicht von dort nehmen (sondern mit filesize() in PHP selbst ermitteln)
 
Zurück