Hobby-Coder: Flat-file Forum in PHP, welcher Ansatz ist besser?

Ich bin dran, eine schlichte Forensoftware in PHP zu coden, wo alles in Flat-Files/Textdateien abgespeichert wird, nun hab ich zwei Lösungsansätze und weiss nicht, welcher besser ist. Bei beiden würde ich die Inhalte eines Beitrags (Datum, Benutzername, Kommentar) mittels der serialize()-Funktion in die Dateien schreiben.

a) Für jeden Thread den ein Besucher erstellt, wird eine Textdatei erstellt. Alle Beiträge zu einem Thread werden der Reihe nach in die gleiche Textdatei abgespeichert.

Z.B. wird Thread Nummer 23 als "23.txt" abgespeichert, mit dem Inhalt:

2010-02-07 18:56,Susi,"Hallo zusammen"
2010-02-07 19:02,Peter,"Hallo Susi"
2010-02-07 21:54,Michael,"Hallo Peter"

(zur besseren Ansicht vereinfacht, ohne serialize-Syntax)

Die Thread-Datei wird geladen und alle Beiträge darin abgeklappert um den Thread mit allen Kommentaren von oben nach unten darzustellen.

Vorteil: Jeder Thread ist schön kompakt in der eigenen Datei.
Nachteil: Die Thread-Dateien werden riesig gross und soweit ich weiss können Arrays in PHP nur eine bestimmte Anzahl an Elementen aufnehmen, d.h. bei einem riesigen Thread können die Textzeilen/Beiträge nicht mehr in ein Array eingelesen und weiterverarbeitet werden?

b) Jeder Beitrag kommt in seine eigene Textdatei mit steigender Nummerierung, zusätzlich wird der Dateiname in eine Thread-Datei hinzugefügt.

"1.txt" enthält: 2010-02-07 18:56,Susi,"Hallo zusammen"
"2.txt" enthält: 2010-02-07 19:02,Peter,"Hallo Susi"
"3.txt" enthält: 2010-02-07 19:34,Stefan,"Hier ein neuer Thread"
"4.txt" enthält: 2010-02-07 21:54,Michael,"Hallo Peter"

In einem anderen Ordner ist dann eine Datei "1.txt" mit dem Inhalt: 1,2,4

Und eine "2.txt" mit: 3

"1.txt" und "2.txt" verweisen somit auf alle dazugehörigen Beiträge eines Threads. Wird z.B. Thread Nummer 1 aufgerufen, werden die Beiträge einzeln aus ihren Dateien geladen und auch untereinander auf einer Seite gezeigt werden.

Vorteil: Die einzelnen Dateien werden nicht allzu gross. Die einen Dateien enthalten die Infos eines einzelnen Beitrag, die anderen bloss Zahlen durch Kommas getrennt.
Nachteil: Viel mehr Dateien, die geöffnet und geschlossen werden müssen

Welche Methode ist effektiver und verbraucht weniger Rechenzeit und sonstige Resourcen für PHP?

  1. Hallo,

    a) Für jeden Thread den ein Besucher erstellt, wird eine Textdatei erstellt. Alle Beiträge zu einem Thread werden der Reihe nach in die gleiche Textdatei abgespeichert.

    und wie bringst du die Threadstruktur zum Ausdruck? Dir fehlt noch die Angabe des Parent-Postings zu jedem Beitrag.

    b) Jeder Beitrag kommt in seine eigene Textdatei mit steigender Nummerierung, zusätzlich wird der Dateiname in eine Thread-Datei hinzugefügt.

    Dito. Die Zusammengehörigkeit der einzelnen Beiträge fehlt.

    Welche Methode ist effektiver und verbraucht weniger Rechenzeit und sonstige Resourcen für PHP?

    Ich sag's mal so: Solange die Threads überschaubar klein bleiben, dürften sich beide Varianten nicht viel nehmen. Wenn du viel Traffic hast, auch nicht: Dann sind beide nicht gerade der Brüller.
    Warum magst du die Organisation nicht einer Datenbank überlassen, nachdem die Struktur nochmal geklärt ist?

    So long,
     Martin

    --
    Fettflecke werden wieder wie neu, wenn man sie regelmäßig mit etwas Butter einschmiert.
    1. und wie bringst du die Threadstruktur zum Ausdruck? Dir fehlt noch die Angabe des Parent-Postings zu jedem Beitrag.

      Das wird nicht so wie hier eine Baumstruktur, sondern die Beiträge eines Threads werden von oben nach unten wie bei Vanilla, vBulletin, Invision Board und etlichen Imageboards etc. dargestellt.

      1. Hi,

        und wie bringst du die Threadstruktur zum Ausdruck? Dir fehlt noch die Angabe des Parent-Postings zu jedem Beitrag.
        Das wird nicht so wie hier eine Baumstruktur, sondern die Beiträge eines Threads werden von oben nach unten wie bei Vanilla, vBulletin, Invision Board und etlichen Imageboards etc. dargestellt.

        autsch, also kein richtiges Forum, sondern eins von diesen unübersichtlichen Boards, wo alle Beiträge auf einem Haufen liegen ...

        Ciao,
         Martin

        --
        Lehrer:  Wieviel ist die Hälfte von 8?
        Schüler: Kommt drauf an. Waagrecht 0 und senkrecht 3.
        1. autsch, also kein richtiges Forum, sondern eins von diesen unübersichtlichen Boards, wo alle Beiträge auf einem Haufen liegen ...

          Nein, eins von diesen übersichtlichen Boards wo alle Kommentare schon "aufgeklappt" sind, man sich chronologisch durchlesen kann ohne auf Links zu klicken, so dass man nicht versehentlich das gleiche schreibt wie eine andere Person, weil man deren Kommentar nicht durchgelesen hat wie hier bei einer Baumstruktur :D

          1. autsch, also kein richtiges Forum, sondern eins von diesen unübersichtlichen Boards, wo alle Beiträge auf einem Haufen liegen ...

            Nein, eins von diesen übersichtlichen Boards wo alle Kommentare schon "aufgeklappt" sind, man sich chronologisch durchlesen kann ohne auf Links zu klicken,

            Lässt sich theoretisch auch hier implementieren.

            so dass man nicht versehentlich das gleiche schreibt wie eine andere Person, weil man deren Kommentar nicht durchgelesen hat wie hier bei einer Baumstruktur :D

            Entweder man liest alle Beiträge, dann schreibt man nichts doppelt - oder man tut es nicht, dann schreibt man vielleicht was doppeltes. Die Form es Forums nimmt sich da nichts.

            1. Hi Wouzhuo,

              Lässt sich theoretisch auch hier implementieren.

              Nicht nur theoretisch, das ist hier sogar bereits implementiert ;-)

              Schon mal oben auf "Nested-Ansicht" oder "Listen-Ansicht" geklickt?

              Viele Grüße,
                ~ Dennis.

              1. Nicht nur theoretisch, das ist hier sogar bereits implementiert ;-)

                Schon mal oben auf "Nested-Ansicht" oder "Listen-Ansicht" geklickt?

                Die Listed Ansicht ist unbrauchbar, da Sie nicht chronologisch Sortiert ist, sondern eine Baumstruktur ohne Einrückung darstellt.

                Dadurch hat man die Nachteile eines "Flat"-Forum und einer Baumstruktur in einem.

          2. Hallo,

            autsch, also kein richtiges Forum, sondern eins von diesen unübersichtlichen Boards, wo alle Beiträge auf einem Haufen liegen ...
            Nein, eins von diesen übersichtlichen Boards wo alle Kommentare schon "aufgeklappt" sind, man sich chronologisch durchlesen kann ohne auf Links zu klicken, so dass man nicht versehentlich das gleiche schreibt wie eine andere Person, weil man deren Kommentar nicht durchgelesen hat wie hier bei einer Baumstruktur :D

            kannst du hier auch haben.
            Allerdings geht dann, wie ich schon andeutete, der Zusammenhang verloren, man erkennt also nicht mehr, wer wem geantwortet hat. Das ist IMHO viel wichtiger als die reine chronologische Abfolge. Ich halte daher die reine Listenansicht für einen Rückschritt.

            Dass man erstmal alle Beiträge liest (oder zumindest mal überfliegt), bevor man sich in einem Thread zu Wort meldet, sollte selbstverständlich sein.

            Ciao,
             Martin

            --
            Lehrer:  Wieviel ist die Hälfte von 8?
            Schüler: Kommt drauf an. Waagrecht 0 und senkrecht 3.
            1. kannst du hier auch haben.

              Der Link führt auf einen Beitrag von mir und die Darstellung ist immer noch dieselbe Baumstruktur. Muss ich hier registriert sein um eine andere Darstellung zu sehen?

              Allerdings geht dann, wie ich schon andeutete, der Zusammenhang verloren, man erkennt also nicht mehr, wer wem geantwortet hat.

              Dafür gibt's in fast jeder Forensoftware ja die Zitier-Funktion, die offensichtlich auch hier in einer Baumstruktur angewendet wird (weil es ohne halt doch nicht geht?), von daher ist dies kein Vorteil. Ansonsten lässt sich immer noch manuell über "@Benutzername" und copy & paste ein Beitrag zitieren.

              1. Hallo,

                kannst du hier auch haben.
                Der Link führt auf einen Beitrag von mir und die Darstellung ist immer noch dieselbe Baumstruktur.

                arg, ja - die Forensoftware korrigiert eingesetzte Links immer automatisch so, dass sie der Einstellung des Lesers entsprechen (bei nicht registrierten Nutzern eben der Defaulteinstellung).

                Muss ich hier registriert sein um eine andere Darstellung zu sehen?

                Nein. Du kannst in der Postingansicht einfach auf den Link "Listen-Ansicht" im Kopfbereich klicken; ich weiß aber nicht, ob diese Ansicht dann für die nächsten aufgerufenen Threads auch gilt. Aber wenn du dich hier anmeldest, kannst du diese Ansicht als deine persönliche Standardansicht einstellen, die du dann beim Lesen automatisch bekommst - ebenso wie viele andere nützliche Dinge: Ausblenden einzelner Themenbereiche, Anpassung von Farben und Schriftarten, Ändern der Sortierreihenfolge ...

                Allerdings geht dann, wie ich schon andeutete, der Zusammenhang verloren, man erkennt also nicht mehr, wer wem geantwortet hat.

                Dafür gibt's in fast jeder Forensoftware ja die Zitier-Funktion, die offensichtlich auch hier in einer Baumstruktur angewendet wird

                Das eine schließt das andere nicht aus; ich finde sogar, dass Zitieren und Baumstruktur gar nichts miteinander zu tun haben müssen.

                Ciao,
                 Martin

                --
                Man soll den Tag nicht vor dem Abend loben.
                Und den Mann nicht vor dem Morgen.
                  (alte Volksweisheit)
                1. Hallo,

                  Hallo,

                  Nein. Du kannst in der Postingansicht einfach auf den Link "Listen-Ansicht" im Kopfbereich klicken; ich weiß aber nicht, ob diese Ansicht dann für die nächsten aufgerufenen Threads auch gilt. Aber wenn du dich hier anmeldest, kannst du diese Ansicht als deine persönliche Standardansicht einstellen, die du dann beim Lesen automatisch bekommst - ebenso wie viele andere nützliche Dinge: Ausblenden einzelner Themenbereiche, Anpassung von Farben und Schriftarten, Ändern der Sortierreihenfolge ...

                  Jedoch ist selbst die Listen-Ansicht nicht Chronologisch.

                  Beide Arten haben ihren Vorteil. Hier ist es zwar leichter einzelne Stränge zu verfolgen jedoch schwieriger den Thread als ganzes zu verfolgen.

                  -> Hat man den Thread erst einmal komplett gelesen und möchte beim nächsten mal nur die neuen Posts lesen, dafür muss man entweder Suchen und Scrollen oder Post für Post im Thread-Modus durchklicken.
                  -> Es fehlen Links um zum "parent"-Posting zu springen. Dies ist Problematisch wenn es zu einem Posting viele Antorten gibt und man dies nocheinmal lesen möchte (weil z.b. nur ein brocken zitiert wurde)
                  -> In langen Threads (a la "Ist SelfHTML tot?") ist der Thread-Modus der einzige mit dem man nicht die übersicht verliert, da man sich alle neuen Postings von Hand raussuchen muss.

                  Ciao,
                  Martin

                  mfg Pryos

                  1. Hi!

                    -> Es fehlen Links um zum "parent"-Posting zu springen. Dies ist Problematisch wenn es zu einem Posting viele Antorten gibt und man dies nocheinmal lesen möchte (weil z.b. nur ein brocken zitiert wurde)

                    Du hast jetzt aber nicht übersehen, dass dieser sich bei "Ursprüngliche Nachricht zum Thema [Themenbereich] [Subjekt]" befindet? Oder meintest du was anderes.

                    Lo!

                    1. Hallo

                      Du hast jetzt aber nicht übersehen, dass dieser sich bei "Ursprüngliche Nachricht zum Thema [Themenbereich] [Subjekt]" befindet? Oder meintest du was anderes.

                      Ich habe etwas zu dem Posts vor mir geschrieben. Da ging es um die Strukur von Foren. Übersichtlichkeit und was dieses Forum auch kann.
                      Leider kann ich in der Antwortfunktion in der Thread-Ansicht das Thema und Subject nicht ändern und habe es deshalb auch vergessen.

                      Jedoch denke ich das man dank der Baumstruktur ja sehen sollte, worauf ich mich beziehe und worum es geht ;-)

                      Lo!

                      mfg Pryos

  2. Hi!

    Bei beiden würde ich die Inhalte eines Beitrags (Datum, Benutzername, Kommentar) mittels der serialize()-Funktion in die Dateien schreiben.

    Und du musst dir Gedanken über Dateisperren machen, wenn du nicht im Produktionsbetrieb seltsame und kaum nachvollziehbare Fehler haben möchtest. Mit einem DBMS - und sei es auch nur SQLite - bist du das Problem los und kannst außerdem noch alle bereits vorhandenen Abfragemöglichkeiten nutzen.

    Nachteil: Die Thread-Dateien werden riesig gross und soweit ich weiss können Arrays in PHP nur eine bestimmte Anzahl an Elementen aufnehmen, d.h. bei einem riesigen Thread können die Textzeilen/Beiträge nicht mehr in ein Array eingelesen und weiterverarbeitet werden?

    Davon habe ich noch nichts gehört. Auch das PHP-Handbuch schweigt sich über eine Größenbeschränkung von Arrays aus. Lediglich bei Strings sagt es etwas, aber nur, dass dir der vorhandene Speicher eine Grenze setzt. Diese gilt auch für Arrays. Aber ich denke nicht, dass du Beiträge in Megabytegröße haben wirst, denn man rechnet bei einer Schreibmaschinenseite mit circa 2k, und 1MB wären dann schon 500 Seiten.

    Lo!

    1. Und du musst dir Gedanken über Dateisperren machen, wenn du nicht im Produktionsbetrieb seltsame und kaum nachvollziehbare Fehler haben möchtest. Mit einem DBMS - und sei es auch nur SQLite - bist du das Problem los und kannst außerdem noch alle bereits vorhandenen Abfragemöglichkeiten nutzen.

      Ach Mist. Ich dachte PHP wäre so intelligent programmiert, um mehrfache Zugriffe auf eine Datei nacheinander abzuarbeiten, also die abgeschickten Formulareingaben vom zweiten, dritten,... Benutzer möglicherweise in einem für Seitenbesucher unsichtbaren Cache zwischengespeichert werden, wenn auch nur für wenige Millisekunden, bis die Datei vom Zugriff des ersten Benutzers wieder frei ist.

      Wird bei der Funktion flock() sowas gemacht, oder würden die weiteren Benutzer eine Fehlermeldungen bekommen, dass die Threaddatei gerade nicht geöffnet werden kann und ihre Formulareingaben somit verloren gehen?

      Auf eine Datenbank möchte ich eben verzichten, da dass Skript möglichst simpel sein soll, keine Avatare, keine PMs, auf möglichst jedem Webspace mit PHP und ohne MySQL o.ä. ohne grossen Aufwand installierbar, ohne Mitgliederregistration - die Benutzer sollen sich über Tripcodes identifizieren.

      Wie läuft das mit Dateisperren bei Imageboards? Die meisten Skripte sind noch in Perl geschrieben, benutzen keine Datenbank und gerade diese Foren verursachen z.T. äusserst viel Traffic.

      1. Hi!

        Wird bei der Funktion flock() sowas gemacht, oder würden die weiteren Benutzer eine Fehlermeldungen bekommen, dass die Threaddatei gerade nicht geöffnet werden kann und ihre Formulareingaben somit verloren gehen?

        Unter Unix funktionieren Dateisperren auf freiwilliger Basis. Wenn sich verschiedene Prozesse nicht ins Gehege kommen sollen, müssen sich alle gleichermaßen die Sperren berücksichtigen. Das heißt, eine gesperrte Datei kann trotzdem von anderen mit fopen() geöffnet werden. Jeder muss selbst flock() befragen, ob eine Sperre existiert.

        Es gibt zwei Arten des flock()-Verhaltens, blocking und non-blocking. Bei blocking wartet die Funktion bis die Sperre freigegeben wurde, bei non-blocking kehrt sie sofort wieder zurück. Du musst dann selbst entscheiden, was du in dem Fall machst, beispielsweise eine Warterunde einlegen oder abbrechen oder sonst was.

        Auf eine Datenbank möchte ich eben verzichten, da dass Skript möglichst simpel sein soll, keine Avatare, keine PMs, auf möglichst jedem Webspace mit PHP und ohne MySQL o.ä. ohne grossen Aufwand installierbar, ohne Mitgliederregistration - die Benutzer sollen sich über Tripcodes identifizieren.

        Eigentlich sollte SQLite mittlerweile zur Grundausstattung gehören. Das ist allgemein gesagt eine (einfach gehaltene) einbaubare Datenbank-Engine, und sie ist seit PHP 5 als per Default freigegebener Extension enthalten. Nach außen hin sieht man nur, dass eine Datei angelegt wurde. Das ist also quasi wie dein dateibasierendes System, nur etwas komfortabler.

        Wie läuft das mit Dateisperren bei Imageboards? Die meisten Skripte sind noch in Perl geschrieben, benutzen keine Datenbank und gerade diese Foren verursachen z.T. äusserst viel Traffic.

        Dazu kann ich nichts konkretes sagen. Lesezugriffe funktionieren auch ohne Sperren problemlos parallel, aber sobald du Schreiben hinzunimmst, musst du die Sperrproblematik berücksichtigen, und dann auch für das Lesen, sonst du liest unter Umständen nur teilweise geschriebenen Dateien.

        Lo!

        1. Eigentlich sollte SQLite mittlerweile zur Grundausstattung gehören. Das ist allgemein gesagt eine (einfach gehaltene) einbaubare Datenbank-Engine, und sie ist seit PHP 5 als per Default freigegebener Extension enthalten.

          :O

          • Die ist standardgemäss aktiviert und kann von Webspace-Hostern auch nicht deaktiviert werden?
          • Obwohl sie als einzelne, leicht kopierbare Datei in einem Ordner liegt, hat sie das Sperrproblem nicht?
          • Die gleichen Injection- und sonstigen Sicherheitsproblemen wie bei anderen Datenbanken werde ich aber auch bei dieser haben?
          1. Hi!

            Eigentlich sollte SQLite mittlerweile zur Grundausstattung gehören.

            • Die ist standardgemäss aktiviert und kann von Webspace-Hostern auch nicht deaktiviert werden?

            Doch, das kann sie, ähnlich wie auch Dateisystemfunktionen verboten werden können.

            • Obwohl sie als einzelne, leicht kopierbare Datei in einem Ordner liegt, hat sie das Sperrproblem nicht?

            Sie löst es selbst.

            • Die gleichen Injection- und sonstigen Sicherheitsproblemen wie bei anderen Datenbanken werde ich aber auch bei dieser haben?

            Du hast bei jedem Kontextwechsel das "Problem", diesen zu berücksichtigen. Bei serialize() übernimmt es die Funktion freundlicherweise selbst. Sicherheitsprobleme bekommt man nur, wenn man das Prinzip nicht verstanden und berücksichtigt hat.

            Lo!

  3. Z.B. wird Thread Nummer 23 als "23.txt" abgespeichert, mit dem Inhalt:

    2010-02-07 18:56,Susi,"Hallo zusammen"
    2010-02-07 19:02,Peter,"Hallo Susi"
    2010-02-07 21:54,Michael,"Hallo Peter"

    Mal eine andere Baustelle. Ich sehe immer wieder dass bei Flatfiles katastrophale Seicherformate gewählt werden.
    Dein Speicherformat hat folgende Mängel:

    • Die Daten sind nur dann verständlich, wenn irgendwo auch die Spaltenüberschrift gespeichert wird.
    • Soll eine Spalte hinzukommen, so muss dies überall aktualisiert werden.
    • ditto wenn eine Spalte obsolet ist.
    • Deine Idee von Feldtrennzeichen ist ziemlich unzuverlässig, es sei denn, du schreibst die Felder mit einer Routine, die aber auch immer auf , und " prüft, und dann andere Begrenzer einführt, was Abfragen wieder kompliziert gestaltet.
      -Eine Abfrage wie "Gib mir alle Daten, die in der zweiten Spalte identisch mit 'Susi' sind" ist schwer möglich

    Ich möchte dir mal den Vorteil von Query-String Formaten und ähnlichem in Erinnerung rufen. Das heisst, speichere den Feldnamen mit dem Feldwert.

    Tabellen sind nur mit SQL DBs sinnvoll.

    mfg Beat

    --
    ><o(((°>           ><o(((°>
       <°)))o><                     ><o(((°>o
    Der Valigator leibt diese Fische