Die Dateiverarbeitung ist ein grundlegender Bestandteil vieler PHP-Anwendungen. Sie ermöglicht das Lesen, Schreiben und Manipulieren von Dateien auf dem Serversystem. In diesem Abschnitt werden die wichtigsten Techniken und Funktionen zur Dateiverarbeitung in PHP vorgestellt.
PHP bietet eine Vielzahl von Funktionen für den Dateizugriff, die sich in verschiedene Kategorien einteilen lassen.
Die grundlegendsten Funktionen sind fopen() zum Öffnen
und fclose() zum Schließen von Dateien:
<?php
// Datei zum Lesen öffnen
$handle = fopen('daten.txt', 'r');
// Arbeiten mit der Datei...
// Datei schließen
fclose($handle);Die Funktion fopen() benötigt zwei Parameter: den Pfad
zur Datei und den Modus, in dem die Datei geöffnet werden soll. Häufig
verwendete Modi sind:
| Modus | Beschreibung |
|---|---|
| ‘r’ | Nur lesen (Datei muss existieren) |
| ‘w’ | Nur schreiben (erstellt Datei, überschreibt bestehende) |
| ‘a’ | Anhängen (erstellt Datei, wenn nicht vorhanden) |
| ‘r+’ | Lesen und Schreiben (Datei muss existieren) |
| ‘w+’ | Lesen und Schreiben (erstellt Datei, überschreibt bestehende) |
| ‘a+’ | Lesen und Anhängen (erstellt Datei, wenn nicht vorhanden) |
PHP bietet verschiedene Methoden zum Lesen von Dateien:
<?php
// Gesamte Datei auf einmal lesen
$inhalt = file_get_contents('daten.txt');
echo $inhalt;
// Datei zeilenweise lesen
$handle = fopen('daten.txt', 'r');
while (($zeile = fgets($handle)) !== false) {
echo $zeile;
}
fclose($handle);
// Datei als Array von Zeilen lesen
$zeilen = file('daten.txt');
foreach ($zeilen as $zeilennummer => $zeile) {
echo "Zeile {$zeilennummer}: {$zeile}";
}Bei größeren Dateien ist es effizienter, die Datei zeilenweise oder in Blöcken zu lesen, anstatt den gesamten Inhalt auf einmal in den Speicher zu laden:
<?php
// Datei in Blöcken lesen
$handle = fopen('grosse_datei.txt', 'r');
$blockgroesse = 1024; // 1 KB
while (!feof($handle)) {
$block = fread($handle, $blockgroesse);
echo $block;
}
fclose($handle);Zum Schreiben in Dateien stehen ebenfalls mehrere Funktionen zur Verfügung:
<?php
// Gesamten Inhalt auf einmal schreiben
file_put_contents('ausgabe.txt', 'Hallo Welt!');
// Mit Anhängen-Option
file_put_contents('log.txt', "Neuer Eintrag: " . date('Y-m-d H:i:s') . "\n", FILE_APPEND);
// Schreiben mit fwrite
$handle = fopen('daten.txt', 'w');
fwrite($handle, "Erste Zeile\n");
fwrite($handle, "Zweite Zeile\n");
fclose($handle);PHP bietet zahlreiche Funktionen zur Arbeit mit dem Dateisystem:
<?php
// Prüfen, ob eine Datei existiert
if (file_exists('config.ini')) {
echo "Die Konfigurationsdatei existiert.";
}
// Prüfen, ob es sich um eine Datei handelt
if (is_file('config.ini')) {
echo "Es handelt sich um eine Datei.";
}
// Prüfen, ob es sich um ein Verzeichnis handelt
if (is_dir('uploads')) {
echo "Es handelt sich um ein Verzeichnis.";
}
// Dateiinformationen abrufen
$info = stat('dokument.pdf');
echo "Größe: " . $info['size'] . " Bytes";
echo "Letzte Änderung: " . date('Y-m-d H:i:s', $info['mtime']);
// Dateigröße ermitteln
$groesse = filesize('dokument.pdf');
echo "Die Datei ist $groesse Bytes groß.";
// Datei umbenennen/verschieben
rename('alte_datei.txt', 'neue_datei.txt');
// Datei kopieren
copy('original.txt', 'kopie.txt');
// Datei löschen
unlink('zu_loeschen.txt');Für die Arbeit mit Verzeichnissen bietet PHP spezielle Funktionen:
<?php
// Verzeichnis erstellen
mkdir('neuer_ordner', 0755);
// Verschachteltes Verzeichnis erstellen
mkdir('pfad/zum/neuen/verzeichnis', 0755, true);
// Verzeichnisinhalt auslesen
$verzeichnis = 'bilder';
$dateien = scandir($verzeichnis);
foreach ($dateien as $datei) {
if ($datei != '.' && $datei != '..') {
echo $datei . "<br>";
}
}
// Alternativ mit DirectoryIterator
$verzeichnis = new DirectoryIterator('bilder');
foreach ($verzeichnis as $datei) {
if ($datei->isFile()) {
echo $datei->getFilename() . " (Datei)<br>";
} elseif ($datei->isDir() && !$datei->isDot()) {
echo $datei->getFilename() . " (Verzeichnis)<br>";
}
}
// Verzeichnis rekursiv durchsuchen
function durchsuche_verzeichnis($pfad) {
$dateien = glob($pfad . '/*');
foreach ($dateien as $datei) {
if (is_file($datei)) {
echo "Datei: $datei<br>";
} elseif (is_dir($datei)) {
echo "Verzeichnis: $datei<br>";
durchsuche_verzeichnis($datei);
}
}
}
durchsuche_verzeichnis('projekte');
// Verzeichnis löschen (muss leer sein)
rmdir('leerer_ordner');PHP bietet Funktionen zur Manipulation und Analyse von Dateipfaden:
<?php
// Teile eines Pfades extrahieren
$pfad = '/var/www/html/uploads/dokument.pdf';
$verzeichnis = dirname($pfad); // /var/www/html/uploads
$dateiname = basename($pfad); // dokument.pdf
$name = pathinfo($pfad, PATHINFO_FILENAME); // dokument
$erweiterung = pathinfo($pfad, PATHINFO_EXTENSION); // pdf
// Pfade zusammenführen
$pfad = __DIR__ . '/uploads/' . $dateiname;
// Alternativ mit realpath
$absoluter_pfad = realpath('.');Für die Verarbeitung von CSV-Dateien (Comma-Separated Values) bietet PHP spezielle Funktionen:
<?php
// CSV-Datei lesen
$handle = fopen('daten.csv', 'r');
while (($daten = fgetcsv($handle, 1000, ',')) !== false) {
echo "Name: {$daten[0]}, E-Mail: {$daten[1]}, Alter: {$daten[2]}<br>";
}
fclose($handle);
// CSV-Datei schreiben
$handle = fopen('export.csv', 'w');
$benutzer = [
['Max', 'max@example.com', 28],
['Anna', 'anna@example.com', 34],
['Tim', 'tim@example.com', 22]
];
foreach ($benutzer as $person) {
fputcsv($handle, $person);
}
fclose($handle);PHP kann auch mit INI-Dateien für Konfigurationen arbeiten:
<?php
// INI-Datei lesen
$config = parse_ini_file('config.ini', true);
echo "Datenbankhost: " . $config['database']['host'];
// INI-Datei schreiben (manuell)
$handle = fopen('config.ini', 'w');
fwrite($handle, "[database]\n");
fwrite($handle, "host = localhost\n");
fwrite($handle, "username = root\n");
fwrite($handle, "password = secret\n");
fclose($handle);Für temporäre Daten, die nur während der Ausführung eines Skripts benötigt werden:
<?php
// Temporäre Datei erstellen
$temp_datei = tempnam(sys_get_temp_dir(), 'prefix_');
file_put_contents($temp_datei, 'Temporäre Daten');
// Mit der temporären Datei arbeiten...
// Temporäre Datei löschen
unlink($temp_datei);Wie bereits im Abschnitt “Arbeiten mit Formularen” angesprochen, können Dateien über HTML-Formulare hochgeladen werden. Hier ein erweitertes Beispiel zur Verarbeitung von Uploads:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['datei'])) {
$datei = $_FILES['datei'];
// Fehlerprüfung
if ($datei['error'] !== UPLOAD_ERR_OK) {
$fehler = [
UPLOAD_ERR_INI_SIZE => 'Die hochgeladene Datei überschreitet die in php.ini festgelegte upload_max_filesize Direktive.',
UPLOAD_ERR_FORM_SIZE => 'Die hochgeladene Datei überschreitet die im Formular festgelegte MAX_FILE_SIZE Direktive.',
UPLOAD_ERR_PARTIAL => 'Die Datei wurde nur teilweise hochgeladen.',
UPLOAD_ERR_NO_FILE => 'Es wurde keine Datei hochgeladen.',
UPLOAD_ERR_NO_TMP_DIR => 'Temporärer Ordner fehlt.',
UPLOAD_ERR_CANT_WRITE => 'Fehler beim Schreiben der Datei auf die Festplatte.',
UPLOAD_ERR_EXTENSION => 'Eine PHP-Erweiterung hat den Upload gestoppt.'
];
die("Upload-Fehler: " . ($fehler[$datei['error']] ?? 'Unbekannter Fehler'));
}
// Sicherheitsüberprüfungen
$erlaubte_typen = ['image/jpeg', 'image/png', 'application/pdf'];
if (!in_array($datei['type'], $erlaubte_typen)) {
die("Dateityp nicht erlaubt. Erlaubte Typen: " . implode(', ', $erlaubte_typen));
}
$max_groesse = 5 * 1024 * 1024; // 5 MB
if ($datei['size'] > $max_groesse) {
die("Datei zu groß. Maximale Größe: 5 MB");
}
// Zielverzeichnis
$zielverzeichnis = 'uploads/';
if (!is_dir($zielverzeichnis)) {
mkdir($zielverzeichnis, 0755, true);
}
// Eindeutigen Dateinamen generieren
$dateiname = pathinfo($datei['name'], PATHINFO_FILENAME);
$erweiterung = pathinfo($datei['name'], PATHINFO_EXTENSION);
$eindeutig = $dateiname . '_' . uniqid() . '.' . $erweiterung;
$zielpfad = $zielverzeichnis . $eindeutig;
// Datei verschieben
if (move_uploaded_file($datei['tmp_name'], $zielpfad)) {
echo "Datei erfolgreich hochgeladen: $zielpfad";
} else {
echo "Fehler beim Verschieben der hochgeladenen Datei.";
}
}Bei der Dateiverarbeitung in PHP sind verschiedene Sicherheitsaspekte zu beachten:
<?php
// Unsicher
$datei = $_GET['datei'];
$inhalt = file_get_contents($datei); // Potenziell gefährlich!
// Sicherer
$datei = basename($_GET['datei']);
$inhalt = file_get_contents('uploads/' . $datei);
// Noch sicherer mit Whitelist
$erlaubte_dateien = ['config.txt', 'info.txt', 'daten.csv'];
if (in_array($_GET['datei'], $erlaubte_dateien)) {
$inhalt = file_get_contents('uploads/' . $_GET['datei']);
}<?php
// Überprüfen der Dateiendung
$erlaubte_endungen = ['jpg', 'png', 'pdf'];
$dateiendung = strtolower(pathinfo($_FILES['datei']['name'], PATHINFO_EXTENSION));
if (!in_array($dateiendung, $erlaubte_endungen)) {
die("Dateiendung nicht erlaubt");
}
// Dateitypen mit finfo überprüfen (zuverlässiger)
$finfo = new finfo(FILEINFO_MIME_TYPE);
$dateityp = $finfo->file($_FILES['datei']['tmp_name']);
$erlaubte_typen = ['image/jpeg', 'image/png', 'application/pdf'];
if (!in_array($dateityp, $erlaubte_typen)) {
die("Dateityp nicht erlaubt");
}<?php
// Datei mit restriktiven Berechtigungen erstellen
$handle = fopen('vertraulich.txt', 'w');
fwrite($handle, 'Geheime Information');
fclose($handle);
chmod('vertraulich.txt', 0600); // Nur für den Besitzer lesbar/schreibbarBei umfangreichen Dateioperationen kann es sinnvoll sein, diese asynchron auszuführen, um die Benutzererfahrung nicht zu beeinträchtigen. Dies wird typischerweise durch das Auslagern in Hintergrundprozesse realisiert:
<?php
// Einfacher Ansatz: Verzögertes Skript mittels Datenbank-Flagging
file_put_contents('verarbeitung_starten.flag', '1');
echo "Dateiverarbeitung wurde im Hintergrund gestartet.";
// Auf dem Server läuft ein Cron-Job, der regelmäßig prüft:
if (file_exists('verarbeitung_starten.flag')) {
unlink('verarbeitung_starten.flag');
// Führe aufwändige Dateioperationen durch
}Für komplexere Szenarien sollten Message Queues oder Job-Systeme wie in den Kapiteln zu “Enterprise-Architektur mit PHP” und “Fortgeschrittene Themen” beschrieben verwendet werden.