Dateien mit PHP in mySQL DB speichern
Hier schreibe ich, wie man eine Datei in einer mySQL Datenbank speichert. Dafür sollte man sich etwas mit PHP und mySQL auskennen. Ich schreibe hier nicht, wie man Dateien auf den Webspace hochlädt. Zudem gehe ich davon aus, dass die Datei schon auf dem Webspace liegt.
Nun ist der Inhalt der Datei in der Variable $content gespeichert.
Jetzt muss der Inhalt der Datei noch in die Datenbank geschrieben werden. Da die Datei in diesem Beispiel ein JPG ist nehme ich ich den Mimetype image/jpeg. Sollte dieser Typ nicht bekannt sein, muss auf die Datei mime.types zurückgegriffen werden. Dieser Mimetype ist wichtig, da er nachher als Content-type an den Browser gesendet wird.
Nun zur mySQL Query:Die Funktion addSlashes() ist wichtig, da es sonst zu mySQL Fehler kommt, da das Zeichen ' im Dateiinhalt sein könnte.
Keine grosse Kunst, allerdings gibt es doch einige Dinge, die man beachten sollte.
Vorbereitungen
Also los. Zuerst zur Datenbank. Prädestiniert für Binärdateien sind die Blobs (Binary Large Objects). Zudem sollte man den Mimetype in der Datenbank speichern, falls der schon, zum Beispiel durch einen Upload bekannt ist. Also sieht die Tabelle zum Beispiel so aus:mysql> describe files; +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | fileID | int(11) | | PRI | NULL | auto_increment | | fileType | varchar(200) | | | | | | fileData | blob | | | | | +----------+--------------+------+-----+---------+----------------+
Daten schreiben
Um die Daten in die DB zu schreiben, muss zuerst den Inhalt der Datei auslesen. Die macht man so:
<?
// die datei, die in die db geschrieben wird
$file="bild.jpg";
// datei oeffnen
// das r steht fuer read und das b fuer binary
$fp=@fOpen($file,"rb")or die("konnte die datei nicht oeffnen");
// daten auslesen
$content=fRead($fp,fileSize($file));
// datei schliessen
fClose($fp);
?>
Jetzt muss der Inhalt der Datei noch in die Datenbank geschrieben werden. Da die Datei in diesem Beispiel ein JPG ist nehme ich ich den Mimetype image/jpeg. Sollte dieser Typ nicht bekannt sein, muss auf die Datei mime.types zurückgegriffen werden. Dieser Mimetype ist wichtig, da er nachher als Content-type an den Browser gesendet wird.
Nun zur mySQL Query:
<?
mysql_query("
INSERT INTO
files
(
`fileType`,
`fileData`
)
VALUES
(
'image/jpeg',
'".addSlashes($content)."'
)");
?>
Daten auslesen
<?
// id setzen. kann auch per $_GET bzw. $_POST geschehen
$id=1;
// daten auslesen
$result=$db->query("
SELECT
fileType,
fileData
FROM
files
WHERE
fileID=".$id);
$type=mysql_result($result,0,"fileType");
$data=mysql_result($result,0,"fileData");
// headers
// den content-type (mimetype) senden. aus der db
header("Content-type: ".$type);
// die groesse des inhalts anzeigen. damit der browser die verbleibende zeit berechnen kann.
header("Content-Length: ".strLen($data));
// die anzeige und der filename der datei.
// content-disposition: attachment oeffnet einen speichern unter dialog
// content-disposition: inline oeffnet das file im browser falls moeglich (pdf)
header("Content-Disposition: attachment; filename=bild.jpg");
echo $data;
?>
Keine grosse Kunst, allerdings gibt es doch einige Dinge, die man beachten sollte.
Kommentare
Michel
27.03.07 09:47
david
27.03.07 10:11
Ich verwende diese Funktionalität momentan, um PDF Dateien zu speicheren. Es hat den Vorteil, dass ich nur die DB und keine sonstigen Datern von der Festplatte speichern muss. Zudem muss ich, beim löschen eines Datensatztes nicht noch die Datei auf der Festplatte entfernen.
Wo es in meiner Meienung auch noch sinn machen würde, ist bei geschützen Bereichen. Manchmal möchte man Dateien nicht allen Benutzern zugänglich machen. Wenn die Datei in einer mySQL DB gespeichert ist, kann man das ganz klar regeln.
Schlussendlich muss man sagen, dass mySQL halt nicht so schnell ist wie das Filesystem und dass dafür auch immer ein zusätzliches Script gestartet werden muss. Allerdings muss man nur die DB sichern.
Ein spezifisches Anwenungsgebiet kann ich dir nicht nennen, am besten Entscheidet man von Fall zu Fall ob sowas sinnvoll ist. Eine Downloadpage würde ich auf jeden Fall nicht so realisieren.
Michel
28.03.07 13:53
Aber werde deine Anleitung trotzdem mal testen. Danke!
Tony
31.03.07 20:56
dominik kessler
15.06.07 16:34
for($i = 0, $Export = ""; $i < mysql_num_rows($ResultPointer); $i++)
{
$Daten = mysql_fetch_object($ResultPointer);
$Spalte[] = str_replace("\"", "\"\"", $Daten->usr_id);
$Spalte[] = str_replace("\"", "\"\"", $Daten->username);
$Spalte[] = str_replace("\"", "\"\"", $Daten->first_name);
$Spalte[] = str_replace("\"", "\"\"", $Daten->last_name);
dominik kessler
15.06.07 16:35
$Spalte[] = str_replace("\"", "\"\"", $Daten->username);
$Spalte[] = str_replace("\"", "\"\"", $Daten->first_name);
david
20.06.07 15:15
der echte Dominik Kessler
16.07.07 12:05
ChrisPHL
09.03.09 10:59
Kann man da zur Laufzeit(!) irgend was mit php "drehen"?
david
09.03.09 21:07
Über Google habe ich einige Links zu Themen gefunden, wo das Problem war, dass die mySQL-Verbindung nicht zum Localhost hergestellt wurde. Wie sieht das bei dir aus? Ist das ein Server beim Hoster oder eins bei dir, wo du die mySQL-Konfiguration anpassen kannst?
Wieland Peter
10.04.09 19:06
Ich nenne diese Art "Stringgefutzel". Verwendet besser mysqli als PHP-Schnittstelle mit prepaired-satements.
Das hier ist TOTAL unsicher.
Macht mal auf diese Weise ne Passwortabfrage und Ihr werdet feststellen, dass man sich einloggen kann, indem man als Passwort 1' or true eingibt.
Mit dem ' schließt man die query und or true liefert der Webseite immer true zurück, so als ob das Passwort richtig wäre.