| Letztes Update: 16.08.2005 17:53:45 |
|
| |
| * Link führt ins Internet |
|
| |
Nützliche Dateioperationen
|
|
Hier haben wir noch einige nützliche Codeschnipsel zur Verarbeitung von Dateien.
Zeilen gezielt auslesen
Die Zeilen einer Datei gezielt auszulesen kann mit einigen Handgriffen umgesetzt werden. Sie können hierbei entweder die Funktion file() oder fgets() einsetzen. Die Funktion file() setzt voraus das genügen freier Arbeitsspeicher zur Verfügung steht, da in ihrem Fall die Datei vollständig eingelesen wird.
Beispiel – file()
<?php
$daten = file("daten.txt");
// Zweite Zeile ausgeben
echo $daten[1];
?>
|
Beispiel - fgets()
<?php
$zeilen_zaehler = 0;
$ziel_zeile = 2;
$datei = fopen('daten.txt','r');
while ((! feof($datei)) && ($zeilen_zaehler < $ziel_zeile)) {
if ($zeile = fgets($datei,1048576)) {
$zeilen_zaehler++;
}
}
fclose($datei);
echo $zeile;
?>
|
Inhalt einer Datei rückwärts einlesen
Nun werden Sie sicher denken, wozu soll das gut sein. Da hätten wir einen kleinen Tipp – denken Sie mal ein Gästebuch. Es ist recht simpel, neue Beiträge mit Hilfe fopen() und dem Anhängmodus „a“ (append) ans Dateiende anzuhängen. Aber wie sieht es mit der Ausgabe aus – der neueste Eintrag soll schliesslich an den Anfang der Ausgabe. Hierfür haben wir eine einfache und praktische Lösung für Sie.
Beispiel
<?php
$daten = file("daten.txt");
$daten = array_reverse($daten);
foreach ($daten as $eintrag) {
echo "$eintrag<br>";
}
?>
|
Natürlich können Sie anstatt sämtliche Zeilen rückwärtig auszugeben, lediglich eine festgelegte Anzahl von Zeilen ausgeben, wie wäre es mit den letzten 10 Zeilen.
Beispiel
<?php
$daten = file('daten.txt');
$anzahl = 10;
for ($i = 0, $j = count($daten); $i <= $anzahl; $i++) {
echo $daten[$j - $i] . "<br>";
}
?>
|
Zeile per Zufall - Spruchgenerator
Wie wäre es mit einem Spruchgenerator, welcher bei jedem Aufruf zufällig eine Zeile ausliest.
<?php
// Zufallsgenerator
function gen_zahl($max = 1) {
$faktor = 1000000;
return ((mt_rand(1,$faktor * $max)-1)/$faktor);
}
// Spruchgenerator
function gen_spruch($dateiname) {
$zeilen_nr = 0;
$datei = fopen($dateiname,'r');
while (! feof($datei)) {
if ($z = fgets($datei,1048576)) {
$zeilen_nr++;
if (gen_zahl($zeilen_nr) < 1) {
$spruch = $z;
}
}
}
fclose($datei);
return $spruch;
}
// Ausgabe
echo gen_spruch("daten.txt");
?>
|
Wie Sie feststellen werden haben wir es uns erlaubt die Zufallszahlen-Funktion gen_zahl() von der Spruchgenerator Funktion gen_spruch() zu trennen, so haben Sie die Möglichkeit die Zufallszahlen-Funktion auch für andere Zwecke zu nutzen.
Sie können es natürlich auch etwas einfacher haben halten, wenn Sie die Funktion file() und anschliessend die Funktion shuffle() einsetzen.
Beispiel
<?php
// Spruchgenerator
function gen_spruch($dateiname) {
$daten = file($dateiname);
shuffle ($daten);
return $daten[0];
}
// Ausgabe
echo gen_spruch("daten.txt");
?>
|
Datei ohne eine temporäre Datei ändern
Stellen Sie sich vor Sie wollen an einer Datei Änderungen vornehmen, dies jedoch ohne eine temporäre Datei zwischenzuspeichern. In diesem Fall öffnen Sie eine Datei mit dem Modus „r+“ und korrigieren nach dem Schreiben der Änderungen die Länge der Datei mit Hilfe der Funktion ftruncate(). Diese ist in der Lage eine Datei auf eine angegebene Länge zu kürzen.
Beispiel
<?php
// Datei zum Lesen und Schreiben öffnen
$datei = fopen('daten.txt','r+');
// Gesamte Datei einlesen
$daten = fread($datei,filesize('daten.txt'));
// Konvertiert *Wort* zu <b>Wort</b>
$daten = preg_replace('@\*(.*?)\*@i','<b></b>',$daten);
// Konvertiert /Wort/ zu <u>Wort</u>
$daten = preg_replace('@/(.*?)/@i','<u></u>',$daten);
// Dateizeiger an den Anfang zurücksetzen
rewind($datei);
// Neue Daten in die Datei schreiben
if (-1 == fwrite($datei,$daten)){
echo "Fehler!";
}
// Dateilänge auf die tatsächliche Datengrösse anpassen
ftruncate($datei,ftell($datei));
// Datei schliessen
fclose($datei);
?>
|
Ihre daten.txt könnte folgende Daten enthalten:
/Matthias/ ist dort
*Caroline* ist hier
|
Nach der Änderung stellt sich der Inhalt, wie folgt dar:
<u>Matthias</u> ist dort
<b>Caroline</b> ist hier
|
Schreiben und Lesen von komprimierten Dateien
Um Daten in komprimierter Form als Datei anlegen zu können steht Ihnen in PHP die zlib-Erweiterung zur Verfügung.
Beispiel - Schreiben
<?php
$datei = gzopen('daten.gz','w');
$daten = "Hier der Text";
if (-1 == gzwrite($datei,$daten)) {
echo "Fehler!";
} else {
echo "Datei erzeugt!";
}
gzclose($datei);
?>
|
Beispiel - Lesen
<?php
$datei = gzopen('daten.gz','r');
while ($zeile = gzgets($datei,1024)) {
echo $zeile;
}
gzclose($datei);
?>
|
Die zlib-Erweiterung enthält zahlreiche Dateizugriffsfunktionen wie gzopen(), gzread() und gzwrite(), welche in der Lage sind Daten beim Schreiben zu komprimieren und beim Lesen zu dekomprimieren. Der von zlib verwendete Kompressions-Algorithmus ist mit den Tools gzip und gunzip kompatibel.
Datei nach einem Muster durchsuchen
Um ein bestimmtes Muster innerhalb einer Datei zu finden und die betroffenen Zeilen auszugeben, sollten Sie sich auf reguläre Ausdrücke und den Funktionen preg_grep(), file() oder fgets() stützen.
Entweder Sie lesen die Datei vollständig mit Hilfe von file() in den Speicher oder Sie gehen Zeilenweise vor in dem Sie die Funktion fgets() einsetzen.
Wir verwenden folgende textdatei:
Inhalt - daten.txt
ActionScript Praxisbuch
ActionScript Profireferenz
MySQL Praxisbuch
PHP 5 Praxisbuch
|
Beispiel – file()
<?php
// Nur Praxisbücher
$muster = "/\bpraxisbuch\b/i";
// Liste der gefundenen Einträge
$prasix_buecher = preg_grep($muster, file('daten.txt'));
// Ausgabe
foreach ($prasix_buecher as $buch) {
echo "$buch<br>";
}
?>
|
Ausgabe
ActionScript Praxisbuch
MySQL Praxisbuch
PHP 5 Praxisbuch
|
Beispiel – fgets()
<?php
// Nur Praxisbücher
$muster = "/\bpraxisbuch\b/i";
// Datei öffnen
@$datei = fopen('daten.txt', 'r') or die("Fehler!");
// Durchsuchen der Datei - Zeilenweise
while (!feof($datei)) {
$zeile = fgets($datei, 4096);
if (preg_match($muster, $zeile)) {
$prasix_buecher[] = $zeile;
}
}
// Ausgabe
foreach ($prasix_buecher as $buch) {
echo "$buch<br>";
}
// Datei schliessen
fclose($datei);
?>
|
Ausgabe
ActionScript Praxisbuch
MySQL Praxisbuch
PHP 5 Praxisbuch
|
Sie sollten noch vollgendes berücksichtigen, die erste Methode ist ungefähr drei- bis viermal schneller als die zweite. Die Zweite Methode benötigt für die Suche jedoch weniger Speicher. In diesem Fall müssen Sie als Entwickler entscheiden, was Ihnen wichtiger ist. Und noch etwas gilt es zu berücksichtigen, die zweite Methode ist nicht in der Lage Zeichenfolgen, die sich über mehrere Zeilen erstrecken, zu finden, da in ihrem Fall der reguläre Ausdruck auf jede Zeile einzeln angewendet wird.
Dateidownload mit PHP
Grundsätzlich können Sie einen Dateidownload auf zwei verschiedene Arten realisieren:
• Man schreibt ein PHP-Skript, das einen Redirect auf die zu ladende Datei generiert.
• Man startet den Download durch das PHP-Skript.
Die Methode mit dem Redirect hat den Nachteil, dass Anwender die Ziel-URL des Redirect mitbekommen und später dann direkt und ungeschützt auf diese Datei zugreifen können.
Will man dies verhindern, muss der Download innerhalb von PHP abgewickelt werden. Die zu ladenden Dateien liegen dann außerhalb der Document Root des Webservers und besitzen somit keine URL. Sie sind lediglich durch PHP abzurufen. In PHP sendet man den passenden MIME-Typ als Header und schickt dann die gewünschte Datei hinterher. Natürlich kann man vorher noch einen Downloadzähler aktualisieren oder überprüfen, ob der Anwender überhaupt für den Download autorisiert ist.
<?php
// $download sei der Bezeichner für die zu ladende Datei
$download = $_GET['download'];
// Dieses Verzeichnis liegt ausserhalb des Document Root und
// ist nicht per URL erreichbar.
$basedir = "/home/www/download";
// Übersetzung von Download-Bezeichner in Dateinamen.
$dateiliste = array(
"file1" => "area1/datei1.zip",
"file2" => "area1/datei2.zip",
"file3" => "area2/datei1.zip"
);
// Einbruchsversuch abfangen.
if (!isset($dateiliste[$download])) die("Datei $download nicht vorhanden.");
// Vertrauenswürdigen Dateinamen erzeugen.
$datei = sprintf("%s/%s", $basedir, $dateiliste[$download]);
// Passenden Datentyp erzeugen.
header("Content-Type: application/octet-stream");
// Passenden Dateinamen im Download-Requester vorgeben,
// z.B. den Original-Dateinamen
$speicher_name = basename($dateiliste[$download]);
header("Content-Disposition: attachment; filename=\"$speicher_name\"");
// Datei ausgeben.
readfile($datei);
?>
|
|
|
|
|
|
|
|
|