Kodokon kodokon.com

Dateien: lesen, schreiben, hochladen, JSON

Dateien lesen und schreiben, Ereignisse protokollieren, Uploads sicher entgegennehmen und deine Daten als JSON speichern.

10 Min. · 3 Fragen

Diese Lektion in Kodokon öffnen

Eine Datei zu lesen braucht nur eine einzige Funktion: file_get_contents() liefert den gesamten Inhalt als Zeichenkette, file() zerlegt ihn in ein Array von Zeilen. Prüfe vor dem Lesen den Zugriff mit is_readable(): Ein kaputter Pfad würde false samt einer Warnung zurückgeben.

PHP
<?php

declare(strict_types=1);

$path = __DIR__ . '/notes.txt';

if (!is_readable($path)) {
    exit("File not found or unreadable.");
}

$content = (string) file_get_contents($path);
echo nl2br(htmlspecialchars($content, ENT_QUOTES));

$lines = file(
    $path,
    FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES
);
echo count($lines) . " non-empty line(s)";
Dieselbe Datei einmal komplett und dann Zeile für Zeile lesen.

Zum Schreiben ersetzt file_put_contents() standardmäßig den gesamten Inhalt. Zwei Flags ändern das: FILE_APPEND hängt am Ende an, statt zu überschreiben, LOCK_EX setzt eine exklusive Sperre, damit zwei gleichzeitige Anfragen ihre Schreibvorgänge nicht vermischen. Das ist das Rezept für ein minimales Anwendungs-Log.

PHP
<?php

declare(strict_types=1);

$logFile = __DIR__ . '/app.log';

$line = sprintf(
    "[%s] New order from %s\n",
    date('Y-m-d H:i:s'),
    'alice@example.com'
);

file_put_contents(
    $logFile,
    $line,
    FILE_APPEND | LOCK_EX
);

echo "Event logged.";
Ein zuverlässiges Anwendungs-Log in wenigen Zeilen.

Datei-Uploads verdienen besondere Sorgfalt. Das Formular muss enctype="multipart/form-data" deklarieren, danach beschreibt PHP die empfangene Datei in $_FILES. Validiere alles: den Fehlercode, die Größe und den echten Typ, den finfo erkennt - niemals die Endung oder den vom Browser angekündigten Typ. Und schließlich sollte nur move_uploaded_file() die temporäre Datei verschieben.

PHP
<?php

declare(strict_types=1);

$maxSize = 2 * 1024 * 1024;
$file = $_FILES['avatar'] ?? null;

if ($file === null || $file['error'] !== UPLOAD_ERR_OK) {
    exit("No valid file received.");
}

if ($file['size'] > $maxSize) {
    exit("File too large (2 MB max).");
}

$info = new finfo(FILEINFO_MIME_TYPE);
$mime = $info->file($file['tmp_name']);
$allowed = ['image/jpeg' => 'jpg', 'image/png' => 'png'];

if (!isset($allowed[$mime])) {
    exit("Format not allowed.");
}

$name = bin2hex(random_bytes(8));
$target = __DIR__ . '/uploads/' . $name
    . '.' . $allowed[$mime];

move_uploaded_file($file['tmp_name'], $target);
echo "Image saved.";
upload.php: Größe, echter Typ und Dateiname unter Kontrolle.

Das Format JSON ist die natürliche Brücke zwischen PHP und dem Rest der Welt: json_encode() serialisiert ein Array, json_decode() macht das Gegenteil. Übergib true als zweites Argument, um assoziative Arrays zu erhalten, und das Flag JSON_THROW_ON_ERROR, um fehlerhaftes JSON in eine klare Ausnahme zu verwandeln statt in ein stilles null.

PHP
<?php

declare(strict_types=1);

$path = __DIR__ . '/tasks.json';

$json = is_readable($path)
    ? (string) file_get_contents($path)
    : '[]';

$tasks = json_decode(
    $json,
    true,
    512,
    JSON_THROW_ON_ERROR
);

$tasks[] = [
    'title' => 'Review the lesson',
    'done' => false,
];

file_put_contents(
    $path,
    json_encode(
        $tasks,
        JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE
    ),
    LOCK_EX
);

echo count($tasks) . " task(s) saved";
Ein Mini-Datenspeicher: lesen, ändern, neu schreiben.

Wissenscheck

Stelle sicher, dass du die wichtigsten Punkte dieser Lektion behalten hast.

  1. Was bewirkt das an file_put_contents() übergebene Flag FILE_APPEND?
    • Es hängt den Inhalt am Ende der Datei an, statt sie zu überschreiben
    • Es legt den übergeordneten Ordner an, falls er nicht existiert
    • Es sperrt die Datei während des Schreibens
  2. Warum solltest du dich zur Prüfung eines Uploads nicht auf $_FILES['avatar']['type'] verlassen?
    • Diesen Schlüssel gibt es nur auf manchen Servern
    • Er funktioniert nur für Bilder
    • Dieser Wert wird vom Browser gesendet und kann gefälscht werden; du musst den echten Typ mit finfo erkennen
  3. Was ändert das zweite Argument true in json_decode($json, true)?
    • Das Dekodieren wirft bei einem Fehler eine Ausnahme
    • JSON-Objekte werden zu assoziativen PHP-Arrays statt zu stdClass-Objekten
    • Schlüssel werden in Großbuchstaben umgewandelt