fwrite überschreibt einfach alles!!!

Hallo zusammen!

Ich habe mal wieder ein Problem. Folgenden Code verwende ich gerade:
[PHP]$datafile = fopen(„…/logbuch.txt“, „r“);
fwrite ($datafile,$date." + „.$_SERVER[‚REMOTE_ADDR‘].“ + „.$path.“\r\n");
fclose ($datafile);[/PHP]

Wie man vielleicht erkennt, will ich den neusten Zugriff auf meine Website ganz oben in der Datei zu stehen haben. Jetzt ist aber das Problem, das PHP mir einfach dann die erste Zeile des alten Dokuments löscht. Als Beispiel:

alte Datei:
26.01.2011-17:37:36 + 188.107.46.219 + main
26.01.2011-17:38:35 + 188.107.46.219 + websites
26.01.2011-17:41:07 + 188.107.46.219 + feedback
26.01.2011-17:41:15 + 188.107.46.219 + impressum
26.01.2011-17:41:20 + 188.107.46.219 + main
26.01.2011-17:41:31 + 188.107.46.219 + websites

neue Datei, nach dem beschreiben:
26.01.2011-17:37:36 + 188.107.46.219 + websites
26.01.2011-17:38:35 + 188.107.46.219 + websites
26.01.2011-17:41:07 + 188.107.46.219 + feedback
26.01.2011-17:41:15 + 188.107.46.219 + impressum
26.01.2011-17:41:20 + 188.107.46.219 + main
26.01.2011-17:41:31 + 188.107.46.219 + websites

Er hat mir einfach die erste Zeile weggelöscht. Kann man da was machen? Wenn ja, wie?

Kann man in PHP eine zum lesen geöffnete Datei beschreiben?

ähhmm… Nein, stimmt.

Aber auch mit r+ läufts nicht besser.

Wo soll er auch hinschreiben, wenn der Dateizeiger ganz am Anfang steht? PHP: fseek - Manual oder a+

Ich hatte einfach die Hoffnung, die es würde wie im Editor funktionieren. Ich setzte meinen Zeiger an den Beginn der Datei und drücke Strg+V. Doch dem ist nicht so.
Aber ich hab ne Idee, wie ich das trotzdem hinbekomme. Ich lese die Datei ein, speicher sie in einer Variable, schreibe in die Datei dass, was neu reinkommen soll und hänge den Rest wieder ran :slight_smile:

Viele Grüße
Stromi

Du musst statt „r+“ → „a+“ nehmen. Siehe Manual:
PHP: fopen - Manual

Eben nicht! Das habe ich auch erst gedacht, doch dann hat sich heruasgestellt, dass es das gleiche bewirkt, wie ich oben geschildert habe.

Passiert bei mir nicht. Da musst Du noch irgendwas falsch haben. Wie sieht der Code insgesamt aus?

Wenn wir das mal an f* demonstrieren wollen:
[PHP]// temp öffnen
$buffer = fopen(‚php://temp‘, ‚r+‘);
// anfangsstring schreiben
fwrite($buffer, ‚prepend string‘);

$file = fopen(‚datei.txt‘, ‚r+‘);
// Datei in Buffer schreiben
while (!feof($file)) {
fwrite($buffer, fread($file, 8192));
}
// beide file-pointer auf Anfang setzen
rewind($buffer);
rewind($file);

// buffer lesen und Datei schreiben
while (!feof($buffer)) {
fwrite($file, fread($buffer, 8192));
}

// Dateigröße neu setzen (Größe des Buffers)
// wäre nicht nötig, da der Buffer automatisch größer ist
ftruncate($file, filesize($buffer));

fclose($buffer);
fclose($file);[/PHP]
Ansonsten geht auch:
[PHP]file_put_contents(‚datei.txt‘, ‚prepend string‘ . file_get_contents(‚datei.txt‘));[/PHP]
kann aber nicht mit sehr großen Dateien umgehen.

Das ist das Problem bei diesem Ansatz. Da das nach einer Art Logfile aussieht, würde ich das nicht so machen.

@ crash: so ähnlich habe ich das auch gelöst.
@ struppi: Folgender, einfacher Code:
[PHP]

<?php error_reporting(-1); ini_set('display_errors', 1); //Fehler ausgeben.. $datafile = fopen("logbuch.txt", "r+"); //datei öffnen fwrite ($datafile,"hallo".$_SERVER['REMOTE_ADDR']."\r\n"); //datei Schreiben fclose ($datafile); //datei schließen echo "hallo"; //test, ob das Skript wirklich läuft - keine Auswirkuungen auf die Funktion des Skriptes ?>

[/PHP]
macht dennoch die gleichen Probleme. Ich versteh das einfach nicht. Wieso geht das bei dir, und bei mir nicht???

Grüße
Stromi

Ich hab nicht gesagt, dass es bei mir geht, sondern dass ich das nicht machen würde, da diese vorgehensweise bei grossen Dateien extrem langsam ist. Schreib deine Loginfos an’s Ende der Datei und gut ist. Denn ansonsten muss immer der komplette Inhalt der Datei eingelesen werden.

r+ und dann reinschreiben geht nicht, weil du damit die Daten überschreibst, nicht am Anfang einfügst. Das ist dein Denkfehler. Wenn du es einfügen wolltest, müsstest du erst die Datei einlesen, dann die Datei komplett neu schreiben mit den neuen Daten am Anfang. Dazu musst du aber die Dateizeiger wieder auf den Anfang setzen.

Ahh, okay. Dann war das ein Missverständins. Ja, ich habs so gelöst, wie du zuletzt genannt hast.

Danke für eure Hilfe!!!

… und wie gesagt, wenn das eine Logdatei ist, dann wird das früher oder später deine Anwendung ziemlich extrem abremsen (und je nach Umgebung kann es auch passieren, dass der Server das Skript komplett abschießt)

[EDIT]Es hat schon seinen Grund, warum in allen Logfiles die neusten Daten am Ende hängen.

hmmm. okay!! Dann häng ich sie auch mal hinten an. :slight_smile: