Fragen zum Zugriffszähler (phpkurs) -> mode bei lesen/schreiben

  • Hallo zusammen,


    ich bin gerade am Kapitel mit dem Zugriffszähler dran und verstehe da die Funktionsweise der verschiedenen modes von fopen, also r,r+,w,w+,a,a+ nicht so ganz und das Verhalten des "rewind"-befehls.


    Folgender Code um einen Zugriffszähler zu erzeugen:


    <?php


    $datei = "seitenaufrufe.txt";


    $handle = fopen($datei, "r");


    $dateigroesse = filesize ($datei);


    $inhalt = fread($handle, $dateigroesse);


    fclose ($handle);


    $inhalt += 1;


    echo "Seitenaufrufe: $inhalt";


    $handle = fopen($datei, "w");
    fwrite ($handle,$inhalt);
    fclose ($handle);


    ?>


    So, aber warum funktioniert dieser Code hier nicht -> es kommt in der Zeile bei fread ein Fehler und der Wert bei der Ausgabe bleibt immer bei 1:


    <?php


    $datei = ("test.txt");


    $handle = fopen($datei, "w+");


    $dateigroesse = filesize($datei);


    $inhalt = fread($handle,$dateigroesse);


    $inhalt += 1;


    fwrite ($handle,$inhalt);


    echo "$inhalt";


    ?>


    Ich stelle mir die Funktionsweise beim letzten Code so vor: die Datei wird, wenn sie durch fwrite geöffnet wird, durch den mode "w+" auf 0 gesetzt am Anfang, wodurch das $inhalt += 1 den Wert immer wieder nur auf 1 setzt. Und vorher bei $inhalt = fread ($handle, $dateigroesse) der Fehler kommt, weil die Datei ja noch leer ist, weil durch w+ auf Null gesetzt.


    Aber im Code darüber mit den zwei fopens wird ja auch "w" benutzt, und der setzt die Datei dann nicht auf Null, sondern da funktioniert der Zähler und erhöht sich schön weiter. Liegt das daran, dass vom fopen "r" das vorher schon ausgelesen wurde und quasi "im gedächtnis" behalten wurde, und damit dann nicht mehr vom fopen "w" auf null gesetzt wird, sondern dann weiter mit $inhalt += 1 weiter hoch gesetzt wird? Also der Datei Inhalt zwar durch "w" gelöscht wird (auf null gesetzt), aber dadurch, dass der Inhalt vorher gelesen wurde von "r", noch zwischengespeichert ist und darauf dann aufgebaut werden kann?



    Meine zweite Frage ist folgende, falls jemand Zeit hat, die auch noch zu beantworten:


    Mit dem rewind Befehl soll der Dateizeiger ja wieder zurück an den "Anfang" gesetzt werden. Bei dem "r" mode für fopen steht aber in der Definition auch, dass der Dateizeiger immer an den Anfang gesetzt wird, nur ist damit aber quasi das andere Ende gemeint, also beides unterschiedlich als "Anfang" definiert ist, richtig? Außerdem wird bei rewind der Dateizeiger nicht nur an den Anfang gesetzt, sondern dieser ersetzt dann auch das was da vorher stand, wenn etwas neu reingeschrieben wird und das ist bei "r" ja nicht der Fall, jedoch ist dies ebenfalls nicht in der Definition oder im Video angegeben, oder übersehe ich da was?
    Ansonsten wäre die Funktionsweise von "rewind" ja definitionsgemäß genau dieselbe wie von dem mode "a", da wird der Dateizeiger ja auch wieder an den Anfang der Datei (also ganz nach links!) gesetzt, was laut definition aber das "ende" der Datei ist. Allerdings wird bei "a" nix ersetzt, sondern nur etwas davor geklatscht, quasi.


    Ich hoffe, ihr versteht was ich meine, und ich konnte es einigermaßen schildern. Grob komm ich gerade nicht mit den modes und dem rewind befehl klar, weil die sich alle etwas widersprüchlich zu dem was man auf php.net liest oder wies im video erklärt wird, verhalten.


    Herzliche Grüße,


    Frank

  • Hallo zusammen,




    So, aber warum funktioniert dieser Code hier nicht -> es kommt in der Zeile bei fread ein Fehler und der Wert bei der Ausgabe bleibt immer bei 1:


    Doku meint:


    "'w+' Zum Schreiben und Lesen geöffnet; platziere Dateizeiger auf Dateianfang und kürze die Datei auf eine Länge von 0. Existiert die Datei nicht, versuche, diese zu erzeugen."


    Zitat


    Ich stelle mir die Funktionsweise beim letzten Code so vor: die Datei wird, wenn sie durch fwrite geöffnet wird, durch den mode "w+" auf 0 gesetzt am Anfang, wodurch das $inhalt += 1 den Wert immer wieder nur auf 1 setzt. Und vorher bei $inhalt = fread ($handle, $dateigroesse) der Fehler kommt, weil die Datei ja noch leer ist, weil durch w+ auf Null gesetzt.


    Ja, richtig gedacht :)


    Zitat


    Aber im Code darüber mit den zwei fopens wird ja auch "w" benutzt, und der setzt die Datei dann nicht auf Null, sondern da funktioniert der Zähler und erhöht sich schön weiter. Liegt das daran, dass vom fopen "r" das vorher schon ausgelesen wurde und quasi "im gedächtnis" behalten wurde, und damit dann nicht mehr vom fopen "w" auf null gesetzt wird, sondern dann weiter mit $inhalt += 1 weiter hoch gesetzt wird? Also der Datei Inhalt zwar durch "w" gelöscht wird (auf null gesetzt), aber dadurch, dass der Inhalt vorher gelesen wurde von "r", noch zwischengespeichert ist und darauf dann aufgebaut werden kann?


    Da wird die Datei zuerst auch auf 0 gesetzt und komplett geleert. Da aber der alte Wert in PHP gespeichert und vergrößert wurde und dann sozusagen neu in die leere Datei geschrieben wird, merkst du das nicht.



    Zitat

    Mit dem rewind Befehl soll der Dateizeiger ja wieder zurück an den "Anfang" gesetzt werden. Bei dem "r" mode für fopen steht aber in der Definition auch, dass der Dateizeiger immer an den Anfang gesetzt wird, nur ist damit aber quasi das andere Ende gemeint, also beides unterschiedlich als "Anfang" definiert ist, richtig?


    Mit Anfang wird hier bei beiden der Anfang der Datei gemeint.


    Zitat


    Ansonsten wäre die Funktionsweise von "rewind" ja definitionsgemäß genau dieselbe wie von dem mode "a",


    Append öffnet/erzeugt die Datei und setzt den Zeiger auf das das Dateinende, rewind setzt den Zeiger in einer geöffneten Datei zurück auf den Dateianfang. ISt also ein beträchtlicher Unterschied und bei weitem nicht das gleich Ergebnis.


    Zitat


    widersprüchlich zu dem was man auf php.net liest oder wies im video erklärt wird, verhalten.


    Das hängt mehr mit deiner Vorstellung eines Zeigers zusammen, als mit den Beschreibungen :D

  • Hey,


    Ich bin ehrlich, ich habe angefangen dein problem zu lesen, und sofort wieder aufgehört.


    Bitte formatiere BB-Codes!


    Es kann doch nciht so schwer sein, deinen PHP code in die dafür vorgesehenen Tags

    Code
    [code=php]

    [/code]
    zu packen!


    Eventuell würden sich dann aucha ndere mehr mit deinem Problem befassen.


    MfG Kanu

  • Hey Nitamud, danke für deine Antwort!


    Gut, dann habe ich das mit dem fopen "w" und "r" ja soweit richtig Kopf :)


    Zitat

    Mit Anfang wird hier bei beiden der Anfang der Datei gemeint.


    Genau, so steht es in der Definition, aber bei mir wird das dann unterschiedlich angesetzt, z.B.:


    <?php


    $datei = "seitenaufrufe.txt";


    $handle = fopen($datei,"r+");


    $dateigroesse = filesize($datei);


    $inhalt = fread($handle,$dateigroesse);


    $inhalt += 1;
    echo "Seitenaufrufe: $inhalt";


    fwrite ($handle,"$inhalt");
    fclose ($handle);


    ?>


    Das sorgt für folgende Zahlenaufrufe: 1, 12, 1213, 12131214 -> der Zeiger wird von "r" also immer rechts angesetzt, ans Ende der Datei. Also -> 1 wird geschrieben, rechts davon kommt die 2 die dochaddiert wurde, dann wieder rechts daneben die 13 etc.


    Wenn ich rewind hinzufüge, werden die Zahlen am ANFANG, also links, ERSETZT. Also direkt zwei gewaltige Unterschiede, jedenfalls bei mir in der Ausgabe.
    Setze ich rewind dazu, kommt nicht wie bei "r" am Ende 1, 12, 1213 etc. hinzu, sondern der Zeiger wird auf Anfang gesetzt und überschreibt mir die alte Zahl -> 1,2,3,4 etc. so wie es funktionieren sollte, aber damit funktioniert der Zeiger auf Anfang ja nicht bei beiden gleich?


    Wahrscheinlich übersehe ich da einfach etwas..



    kanufrosch


    was meinst du damit? Ich habe die Tags aus dem Video genommen, wie ich es da gelernt habe, wenn ich da was übersehen habe, tuts mir leid, ich bin noch recht neu in der Materie.
    Allerdings muss ich auch hinzufügen, dass ich es bescheuert finde, jmd einen Verpackungsfehler vorzuwerfen wenn man selber soviele Fehler in 4 Sätzen fabriziert.

  • Zitat

    Genau, so steht es in der Definition, aber bei mir wird das dann unterschiedlich angesetzt, z.B.:


    Durch den Leseprozess verschiebst du den Zeiger ja immer weiter bis ans Ende deiner File, anfangs ist er aber am Anfang der Datei. Du kannst dir ja vor und nach dem Lesen , die Zeigerposition zurückgeben lassen mit ftell(), dann siehst du das genau :)



    Zitat

    was meinst du damit?


    Er meint damit, das du hier im Forum alles was Php-Quellcode ist, in die [code=php] tags stecken sollst, damit es hier lesbarer präsentiert wird(Highligting, Einrückung).


    Mfg

  • Zitat

    Durch den Leseprozess verschiebst du den Zeiger ja immer weiter bis ans Ende deiner File, anfangs ist er aber am Anfang der Datei. Du kannst dir ja vor und nach dem Lesen , die Zeigerposition zurückgeben lassen mit ftell(), dann siehst du das genau :)


    Also muss ich mir das dann so vorstellen, dass bei "r+" bei fwrite ($handle, $inhalt) erst der $inhalt gelesen wird, der Zeiger ans Ende rückt, und da dann an der Stelle weiter geschrieben wird?


    Aber was macht die Unterscheidung zwischen "a" und "r" dann für einen Sinn, wenn der Zeiger sowieso nach dem Leseprozess am Ende der Datei sitzt? Bei "a" erhalte ich genau dasselbe Ergebnis und der Zeiger sitzt auch an genau derselben Stelle, wenn ich es damit zählen lasse.


    Und danke nochmal für die Hilfe!

  • Der Unterschied liegt vor allem in der Anfangsposition des Zeigers. a setzt ihn soforf auf das Ende , r hingegen setzt ihn an den Dateianfang. a, macht wie der Name "append" andeutet, dann Sinn wenn man etwas an eine bestehenden Datensatz anfügen will :)

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!