fwrite überschreibt den letzten Beitrag!
Thomas
- php
Hallo,
Ich habe mit einem Freund für unsere Seite ein Gästebuchscript entworfen.
Gab zwar ab und zu Probleme, hat aber schließlich doch geklappt.
Später haben wir es umfunktioniert in eine News-Poster. Also, Man kann jetzt über ein Form, News schreiben, diese werden gespeichert in einer TXT und anschließend wird diese TXT in die News-Seite Includiert.
Mein Problem ist das:
Zuerst hat das script neue news immer hinten angehängt in der TXT,
dann hat mir jemand gesagt, ich solle bei $datei = fopen("gaestebuch.txt", "r+"); statt dem "a" was vorher war einfach "r+" einfügen.
So, das hab ich gemacht, doch nun überschreibt das script immer den vorherigen Beitrag. Was ich gerne hätte wäre, dass Neue Beiträge immer ganz nach oben in die TXT kommen. Wie mach ich das jetzt? Warum wird der Beitrag immer ersetzt?
Hier mal mein ganzes script (Ohne Formular. Das ist in einer html datei)
____________________________________
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>News</title>
</head>
<body>
<?php
$user = $_POST["Name"];
$user = htmlentities($user);
$inhalt = $_POST["inhalt"];
$inhalt = htmlentities($inhalt);
$inhalt = str_replace("\n", "<br>", $inhalt);
$email = $_POST["EMail"];
$email = htmlentities($email);
if ($inhalt == "" or $user == "")
{
echo "Sie müssen das Feld "Namen"
und "Inhalt" ausfüllen";
}
else
{
$datum= date("d.m.Y H:i:s");
$eintrag=
"<div class="post">
<h1 class="title">$user</h1>
<p class="byline"><small>$datum</small></p>
<div class="entry">
<p><strong>$inhalt</strong></p>
</div>
</div>";
$datei = fopen("gaestebuch.txt", "r+");
fwrite($datei, "\n".$eintrag);
fclose($datei);
echo "Ihr Eintrag wurde erfolgreich gespeicherty<br> <a href="../acp/Subrosa4Life.html">Back</a>";
}
?>
</div>
</body>
</html>
____________________________________
Hello,
$datei = fopen("gaestebuch.txt", "r+");
fwrite($datei, "\n".$eintrag);
fclose($datei);
Stelle Dir eine Datei vor, wie einen Bindfaden.
Immer, wenn ein Satz zuende ist, ist ein Knoten drin ;-)
Das ist aber auch nur mein Vorstellungsmodell für die Hervorhebung des Satzendes, denn eigentlich müsstest Du den Bindfaden bei einer "normalen Textdatei" nur mit Deinen 256-Farben-Buntstiften anmalen. Jedes Zeichen hat eine eigenen Farbe und das Zeilenende eben eine ganz bestimmte. Wenn Du die aber mit einer anderen übermalst, ist kein Zeilenende mehr vorhanden und aus zwei Sätzen wird einer.
Das Modell mit den Knoten ist da schon brauchbarer. Mach die Knoten in regelmäßigem Abstand. Dann passt immer genau ein Datensatz zwischen zwei Knoten. Drüber wegmalen ist verboten.
Das ist dann eine Daten mit wahlfreiem Zugriff (Random Access). Wenn Du den 17ten Datensatz suchst, musst Du vom Anfang nur 16 Knoten weiterrutschen.
Das, was Du machst ist, immer den ersten Datensatz und ggf. sogar noch ein Stück vom zweiten (oder auch noch vom dritten) wieder überschreiben, denn nach dem Öffnen steht der Schreib-Lesezeiger der Datei immer auf Anfang.
Ein harzliches Glückauf
Tom vom Berg
Wie bitte???
Das hab ich jetzt nicht verstanden. Nur soviel, dass ich immer das Satzende überschreibe und dann werden aus 2 Sätzen einer.
kannst du mir bitte sagen wie ich meinen Fehler jetzt behebe?
p.s. Du bist einfach zu schlau für mich *haha*
Hello,
Das hab ich jetzt nicht verstanden. Nur soviel, dass ich immer das Satzende überschreibe und dann werden aus 2 Sätzen einer.
kannst du mir bitte sagen wie ich meinen Fehler jetzt behebe?
p.s. Du bist einfach zu schlau für mich *haha*
Wie meinst Du denn das nun wieder?
Ich habe ja scheinbar nicht begriffen, wo ich Dich abholen kann.
Also muss ich noch viel lernen - oder Du das nächste Mal mehr Informationen geben?
Zurück zum Thema:
Du öffnest Deine Datei zum Lesen und Schreiben
$datei = fopen("gaestebuch.txt", "r+");
Der Dateizeiger steht danach automatisch am Anfan der Datei.
Die Datei enthält aber schon Daten. Also kann der Dateizeiger eigentlich bis zum Ende vorrücken.
Du veranlasst aber das Vorrücken nicht, sondern lässt ihn dort stehen, wo der Datenbereich beginnt.
fwrite($datei, "\n".$eintrag);
nun schreibst Du strlen($eintrag) + 1 für das "\n" neue Daten dorthin, wo die alten bereits gespeichert sind, überschreibst also die alten Daten.
Da Du mit einem "\n" anfängst, das ja auf Linux-Systemen ein Satzende markiert in Textdateien, suggeriertst Du Deinem System,
Was mit dem dritten und nachfolgenden Datensätzen passiert, hängt von der Länge von $eintrag ab.
Nur mal so zu meiner Weiterbildung:
Hast Du Dir denn einen Bindfaden geholt vorhin und diesen bunt angemalt?
Das kannst Su sicherlich auch auf Papier simulieren.
Nur, hast Du irgend etwas in dieser Richtung unternommen, um meinem Modell zu folgen?
Wenn nicht, dann solltest Du das nun schnellstens nachholen. Zumindest in Gedanken.
Ein harzliches Glückauf
Tom vom Berg
Also jetzt hab ich verstanden was du meinst...Achja, ich hab versucht das mit dem Bindfaden in gedanken nachzuvollziehen...jetzt weis ichs ja...Danke schonmal...
Ich kenn jetzt zwar mein Problem, weis aber nicht wie ichs lösen soll.
Ich kann nur wenig php und lerne noch, aber mein freund ist grade nicht zu erreichen sonst würd ich ihn ja fragen. kannst du mir bitte kurz genau sagen was ich ändern muss? Bitte =(
Hello,
Ich kann nur wenig php und lerne noch, aber mein freund ist grade nicht zu erreichen sonst würd ich ihn ja fragen. kannst du mir bitte kurz genau sagen was ich ändern muss? Bitte =(
Ganz kurz wird das nicht gehen, weil Du noch zuviele Fehlerquellen vor Dir hast, die Dir hier noch niemand unter die Nase gerieben hat.
Der praktische Umgang mit Dateien hängt im Wesentlichen vom verfügbaren Hauptspeicher ab. Wenn man genug davon zur Verfügung hat, wird alles ganz einfach, weil man die Dateien dann vollständig einlesen kann. Wenn man im Verhältnis zur Größe der Dateien nicht genügend Hauptspeicher zur Verfügung hat, muss man sich auch seine Intelligenz besinnen und dann wird es wirklcih spannend.
Machen wir es also erstmla für Blöde *äh* entschuldige bitte, für Leute mit genügend Hauptspeicher.
Gehen wir mal davon aus, Deine Datei passt mehrfach und vollständig in den Hauptspeicher.
Dann können wir sie einfach auslesen und den neuen Satz davor einfügen:
$fh = fopen($dateiname, 'rb+'); ## vorhandene Datei zum Lesen und Schreiben öffnen
flock($fh, LOCK_EX); ## Dem System sagen, jetzt will ICH die Datei haben
## und soalange darf sie kein anderer benutzen
$filesize = filesize($dateiname); ## Die Größe der Datei abfragen, solange sie mir gehört
$dateiinhalt = fread($fh, $filesize); ## Den gesamten Inhalt der Datei auslesen
fseek($fh, 0, SEEK_SET); ## Den Dateizeiger wieder auf den Anfang zurückstellen
## weil er bem Lesen vserstellt worden ist
fwrite($fh, $neuer_Satz . "\n" . $dateiinhalt); ## Neuen datensatz, Satzendezeichen und
## alten Dateiinhalt in die Datei schreiben
## eindeutig _verlängert_ wurde und keinesfalls
## verkürzt. Bitte fragen, wenn es nötig ist
fclose($fh); ## Datei wieder schließen und Sperre ( flock() ) damit
## auch aufheben. (Bitte das flock nicht separat aufheben!)
So kann Dein Problem gelöst werden, wenn die Datei und einiges mehr vollständig in den Hauptspeicher passt.
Ein harzliches Glückauf
Tom vom Berg
Hallo
Das hab ich jetzt nicht verstanden. Nur soviel, dass ich immer das Satzende überschreibe und dann werden aus 2 Sätzen einer.
Nein, du überschreibst den bereits bestehenden Dateiinhalt. Lies im Manual zu fopen in der "Liste von möglichen Modi für fopen()", welchen der Modi du für welchen Fall benutzen solltest.
Tschö, Auge