Zeilenweise in Textdatei schreiben

Hallo,
ich beschäftige mich jetzt seit ca. 1 Woche mit php und hab folgende Frage:
Wie kann ich Zeilenweise in eine Textdatei schreiben?

Ich möchte ein Gästebuch programmieren und die Einträge in einer Textdatei speichern. Um besser drauf zu zugreifen zu können möchte ich einen Eintrag (Name Datum Kommentar) in einer Zeile speichern.

Bin auch offen für andere Vorschläge oder weitere Tipps zu diesem Thema.

mfg
christian

unschön
vorab eine kurze Antwort - Ein Zeilenumbruch in einer Textdatei wird meistens mit \n erreicht. es gibt dann noch \r und noch ne Kombination ich glaub \r\n war das… wenn ich mich recht erinnere braucht unix das für nen richtigen Umbruch, aber da bin ich mir seeehr unsicher…

Generell ist es aber pfui ein GB in einer Textdatei abzulegen. Man denke nur daran, wenn bei jedem Aufruf eine 50 MB Datei geöffnet und komplett ausgelesen werden müsste um vllt 50 Beiträge auf einer Seite anzuzeigen. Gut, da lässt sich streiten, ob es besser wäre 50 kleine Dateien zu öffnen, in denen nur ein Beitrag steht…
Am besten wäre aber sicher eine Datenbank…

Alternativ könntest Du für jeden Monat/jede Woche etc eine neue Datei anlegen und die im bedarfsfall auslesen, aber der Programmieraufwand wäre ungleich höher…

Falls Du noch garnicht weisst wie man überhaupt in eine Textdatei schreibt bietet php.net unter den Stichwörtern
fopen
fwrite
fclose
ein paar Beispiele…

HTH
Munich

thx erstmal
ja an datenbank hab ich auch schon gedacht, aber hab keine ahnung was und vor allem wie ich das umsetzen soll. ich hab eine kleine privte homepage und rechne nicht mit viel einträgen und mir geng es im vordergrund um php

zu fwrite: aber ich kann doch nicht einfach \n in den Text schreiben das wird doch als ganz normaler text verarbeitet.

mfg
charistian

thx erstmal

np :wink:

ja an datenbank hab ich auch schon gedacht, aber hab keine
ahnung was und vor allem wie ich das umsetzen soll.

schau Dir mal http://www.schattenbaum.net/php/ an.
Da wird glaub ich im Tutorial ein kleiner counter erklärt der in eine Textdatei schreibt. Wenn das mysql Tutorial genauso verständlich ist wie der php teil sollte der Link nie fehlen…

ich hab
eine kleine privte homepage und rechne nicht mit viel
einträgen und mir geng es im vordergrund um php

gute Einstellung ;D

zu fwrite: aber ich kann doch nicht einfach \n in den Text
schreiben das wird doch als ganz normaler text verarbeitet.

doch.
Es gibt ein paar Sonderzeichen in php, die anders interprätiert werden. Alle diese Sonderzeichen sind daran zu erkennen, dass man sie „escapen“ muss also einen Backslash voranstellen. Dazu gehört u.a.
\n bzw \r für einen Zeilenumbruch
\ für einen angezeigten Backslash
" für ein angezeigtes „Gänsefüsschen“ :wink:
$ um aus einer Variable einen Text zu machen

php wandelt das dann quasi um und macht ein „enter“ daraus.
und schon ist die nächste Zeile dran…
Allerdings ist das wie gesagt mit vorsicht zu geniessen, denn jede Zeile bricht irgendwann um wenn sie zu lang wird…
Ausserdem werden diese \n’s automatisch auch in die Textdatei geschrieben, wenn in einem textarea-Feld ein Zeilenumbruch steht. Wenn Du im Textfeld ein \n einfügst wird das allerdings als \n verarbeitet und es steht in der Textdatei wirklich dieses \n drin…

vorab eine kurze Antwort - Ein Zeilenumbruch in einer
Textdatei wird meistens mit \n erreicht. es gibt dann noch \r
und noch ne Kombination ich glaub \r\n war das… wenn ich
mich recht erinnere braucht unix das für nen richtigen
Umbruch, aber da bin ich mir seeehr unsicher…

\n reicht

Generell ist es aber pfui ein GB in einer Textdatei abzulegen.

Pfui ist es ein kleines GB in einer Datenbank zu speichern, es gibt eine gewisse Anzahl von Datensätzen bis zu der eine Textdatei besser geeignet ist als eine Datenbank - zumal das verarbeiten mit fgetcsv viel simpler ist als SQL zu verwenden. Die genau anzahl muss man durch testen rausfinden.

Man denke nur daran, wenn bei jedem Aufruf eine 50 MB Datei
geöffnet und komplett ausgelesen werden müsste um vllt 50
Beiträge auf einer Seite anzuzeigen. Gut, da lässt sich
streiten, ob es besser wäre 50 kleine Dateien zu öffnen, in
denen nur ein Beitrag steht…
Am besten wäre aber sicher eine Datenbank…

Ich lese immer nur die 10 Einträge die ich gerade brauche aus der Text Datei - mach ich was falsch? Ab 10 Einträge pro Tag würde ich auch eine Datenbank nehmen.

Alternativ könntest Du für jeden Monat/jede Woche etc eine
neue Datei anlegen und die im bedarfsfall auslesen, aber der
Programmieraufwand wäre ungleich höher…

Falls Du noch garnicht weisst wie man überhaupt in eine
Textdatei schreibt bietet php.net unter den Stichwörtern
fopen
fwrite
fclose
ein paar Beispiele…

Geheimtipp
fgetcsv

Meine Lösung, nicht schön aber funktioniert:

include ("inc/template.inc"); // phplib-template einbinden

$i0 = $\_GET['l'];
if(!$i0){
$i0 = 1;
}
$func = $\_GET['f'];
$v = $\_GET['v'];
$p = $\_GET['p'];
$m = $\_GET['m'];
$name = $\_GET['name'];
$name = htmlentities($name, ENT\_QUOTES);
$email = $\_GET['email'];
$hp = $\_GET['hp'];
if(!$hp){
 $hp = "http://";
}
$eintrag = $\_GET['eintrag'];
$eintrag = htmlentities($eintrag, ENT\_QUOTES);
$sz = $\_GET['sz'];

switch ($func)
{ 
 case 1:
 gb($i0, $v, $p, $m, $name, $email, $hp, $eintrag);
 break;

 default: //zum Navigationsframe
 detail($i0, $v, $p, $m, $sz, $name, $email, $hp, $eintrag, $fehler);
 break; 
}
function gb($i0, $v, $p, $m, $name, $email, $hp, $eintrag)
{
 $dateiname = "csv/gb.csv"; 

 if(!$name){
 $fehler = "

Bitte tragen Sie Ihren Namen ein!";
 detail($i0, $v, $p, 8, 0, $name, $email, $hp, $eintrag, $fehler);
 break;
 }

 if(!$eintrag){
 $fehler = "

Das Feld \"Eintrag\" ist leer";
 detail($i0, $v, $p, 8, 0, $name, $email, $hp, $eintrag, $fehler);
 break;
 }

 if(file\_exists($dateiname))
 {
 $datei = fopen($dateiname, "r");
 $hptest = strlen($hp);
 if($hptest ",$dummy[$i]); 
 $i++;

 while($zeile = fgetcsv($datei,5000,"|")){
/\* die Datei auslesen und im Array zeile zwischenspeichern und in dummy implodieren - mit | Trennern für csv \*/
 $zeile[0]++;
 $dummy[$i] = implode("|", $zeile);
 $i++; 

 } 

 fclose($datei); 
 }
 }
 else{
 echo "keine Datei";
 }
 $text = implode("\n", $dummy); /\* dummy implodieren und als trenner ein \n(zeilenumbruch) benutzen 1|2 \n 2|3 \*/

 $text = ereg\_replace("{","", $text);
 $text = ereg\_replace("}","", $text);
 $text = ereg\_replace("
","
", $text);
 $text = ereg\_replace("","", $text); /\* Leerzeichen weil sonst w-w-w die Tags ausführt \*/
 $text = ereg\_replace(" u\>","", $text);
 $text = ereg\_replace("","", $text);
 $text = ereg\_replace(" b\>","", $text);
 $text = ereg\_replace("","", $text);
 $text = ereg\_replace(" i\>","", $text);

 $datei2 = fopen($dateiname, "w");

 if($datei2)
 {
 fputs($datei2, $text);
 fclose($datei2); /\* den Plunder in die Datei schreiben, der alte Inhalt wird dabei übeschrieben \*/
 }

 //mail("[email protected]", "Gaestebucheintrag", "Heute wurde von $name folgendes in das Gaestebuch eingtragen: \n $eintrag \n") or die ("kann Mail nicht verschicken");

 detail($i0, $v, $p, 8, 0, "", "", "http://", "", "");
}

Dann kommt noch die Funktion detail aber die ist hier nicht wichtig.
Kritik, Fehler gefunden? Her damit.

Gruss Jan

hm… noch nicht ganz
ja… also,
anders:
ich hab jetzt folgenden code:

$file = fopen(„gaestebuch.txt“, „r“);
fwrite($file,($kommentar));
fclose($file);
?>
Wie bekomm ich hin, dass wenn ich speicher jedes mal genau eine Zeile benutzt wird. Die Textdatei soll dann so aussehen:

Kommentar1
Kommentar2
Kommentar3
Kommentar4

aber sie sieht so aus:

Kommentar1Kommentar2KommentarKommentar4

Was kann ich da tun?

hallo
sry ebend erst gesehen …

*schluck*

das muss ich erstmal verarbeiten … trotzdem thx

mfg
christian

wie gesagt
\n verwenden…

siehe hier:

$kommentar .= „\n“;

$file = fopen(„gaestebuch.txt“, „r“);
fwrite($file,($kommentar));
fclose($file);
?>

Fragen dazu?
(den Punkt vor dem = nicht vergessen ansonsten müsstest Du $kommentar = „$kommentar\n“; schreiben.

Christian, lass Dich von dem Code nicht abschrecken, er ist auch für mich schwer zu verstehen, weil die Variablennamen nicht gerade selbstsprechend gewählt sind und sowohl eingabeformular als auch die anderen Funktionen noch fehlen…

Für Dich, Christian, könnte aber der Teil hier interessant sein…

 $z = 1;
 $zeil[0] = $z;
 $zeil[1] = stripslashes($name);
 $zeil[2] = $email;
 $zeil[3] = $hp; 
 $zeil[4] = stripslashes($eintrag);
 $zeil[5] = date("d.m.Y"); /\* Daten aus dem Forumlar in $zeil schreiben \*/

 $dummy[$i] = implode("|", $zeil); /\* zeil implodieren und im array dummy speichern, 1|2|3| eben wie es für eine csv Datei nötig ist \*/
 $dummy[$i] = ereg\_replace("\r","",$dummy[$i]); 
 $dummy[$i] = ereg\_replace("\n","
",$dummy[$i]); 
 $i++;

Da wird ein array erstellt
key 0 enthält die erste Zeile
key 1 enthält die zweite Zeile usw.
danach wird das array zu text umgewandelt und mit |-Zeichen getrennt (Wenn sowas im Text vorkommt wäre das ungünstig. Besser wäre es wenn schon komplexere Kombinationen zu verwenden)
Dann wird noch das oben erwähnte \r rausgeschmissen und der Textbasierte Zeilenumbruch \n wird in html-umbrüche gewechselt.
Jan, verwende da doch >>br /

Christian, lass Dich von dem Code nicht abschrecken, er ist
auch für mich schwer zu verstehen, weil die Variablennamen
nicht gerade selbstsprechend gewählt sind und sowohl
eingabeformular als auch die anderen Funktionen noch fehlen…

Naja ich verwende Templates und trenne HTML strikt von PHP

Für Dich, Christian, könnte aber der Teil hier interessant
sein…

genau und das auslesen der alten Datei + in den Array schreiben. csv Dateien sind eigentlich komma getrennt, http://www.oio.de/m/eai/comma-separated-values.htm wobei man jeden beliebigen Trenner nehmen darf. Mit fgetcsv ist das lesen dann sehr einfach.

$z = 1;
$zeil[0] = $z;
$zeil[1] = stripslashes($name);
$zeil[2] = $email;
$zeil[3] = $hp;
$zeil[4] = stripslashes($eintrag);
$zeil[5] = date(„d.m.Y“); /* Daten aus dem Forumlar in
$zeil schreiben */

$dummy[$i] = implode("|", $zeil); /* zeil implodieren
und im array dummy speichern, 1|2|3| eben wie es für eine csv
Datei nötig ist */
$dummy[$i] = ereg_replace("\r","",$dummy[$i]);
$dummy[$i] = ereg_replace("\n","
",$dummy[$i]);
$i++;

Da wird ein array erstellt
key 0 enthält die erste Zeile
key 1 enthält die zweite Zeile usw.
danach wird das array zu text umgewandelt und mit |-Zeichen
getrennt (Wenn sowas im Text vorkommt wäre das ungünstig.
Besser wäre es wenn schon komplexere Kombinationen zu
verwenden)
Dann wird noch das oben erwähnte \r rausgeschmissen und der
Textbasierte Zeilenumbruch \n wird in html-umbrüche
gewechselt.
Jan, verwende da doch >>br /

$$text = implode("\n", $dummy);

$text = ereg_replace("{","", $text);
$text = ereg_replace("}","", $text);
$text = ereg_replace("& lt;br& gt;","
„, $text);
$text = ereg_replace(“& lt;u& gt;","", $text);
$text = ereg_replace("& lt;/u& gt;","", $text);
$text = ereg_replace("& lt;b& gt;","", $text);
$text = ereg_replace("& lt;/b& gt;","", $text);
$text = ereg_replace("& lt;i& gt;","", $text);
$text = ereg_replace("& lt;/i& gt;","", $text);
Die Leerzeichen nach dem & müssen natrlich weg. Das Skript benutze ich öfter und manchmal lass ich i, u, b zu deswegen ist der Teil hier drin.

hm… ja schön und gut, aber ich will ja die zeilen hinein- und nicht herausbekommen. wenn ich das mit dem \n versuche kommen so komische kästchen und es wird nichts gespeichert. kann das mit englischen betriebssystem zusammenhängen?

mfg
christian

PS: so langsam hab ich keinen bock mehr

thx, alles klaro jetzt

„\n“ --> „\r\n“ :smile:

mfg
christian