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)