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.

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);
?>
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:
<?
mysql_query
("
    INSERT INTO
        files
        (
            `fileType`,
            `fileData`
        )
    VALUES
        (
            'image/jpeg',
            '"
.addSlashes($content)."'
        )"
);
?>
Die Funktion addSlashes() ist wichtig, da es sonst zu mySQL Fehler kommt, da das Zeichen ' im Dateiinhalt sein könnte.

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.

Von Spamfressern und Designänderungen

Ich bin entzückt. Seit dem Einbau des neuen Spamfilters am Samstag habe ich keinen einzigen Spambeitrag mehr erhalten. Und da bin ich froh. Der Counter, den ich gestern noch eingebaut habe zeigt schon 156 Versuche an. Und das in knapp 24 Stunden. Lieber in einem Counter als in meiner Datenbank. Auch Yoda versucht die Spamer auszutricksen. Wie erfolgreich er ist, wird sich sicher noch zeigen.
Zudem habe ich heute noch einwenig am Design geschraubt. Grundsätzlich bin ich damit ja zufrieden, nur das Logo gefällt mir nicht so. Ich habe nun mal einen Verlauf reingezogen und die Schrift verändert, aber wirklich zufrieden bin ich noch nicht. Leider bin ich grafisch nicht so begabt. Vieleicht werde ich aber noch Fotos in den Header aufnehmen, wenn ich mal Zeit habe.
Sollte jemand aber grafisch begat sein und genug Zeit haben, so sage ich bei einem guten Logo nicht nein :)