Langen Text aus Txt-Datei in Seiten unterteilen PHP

pcklick

Grünschnabel
Hi Leute,
folgendes Problem: Ich möchte einen langen Text aus einer Txt-Datei auslesen und diesen anschliessend in mehrere Seiten unterteilen. Leider kann ich dies mit meinem Code nicht tun. Nur wenn ich den langen Text direkt in der PHP-Datei gesetzt hatte, ging dies (also $text = "laanger text" ging). Jegliches auslesen jedoch nicht auch nicht per POST oder GET. Kann mir jemand helfen? Oder mich verbessern? Hier der Code:

PHP-Code:


Code:
$fp = fopen("data.txt","r");

 if ($fp)
  {
    while(!feof($fp))
     {
       $text = fgets($fp);
       echo $text;
      }
 
    fclose($fp);
   }  
echo $text;
$bps = 20; // min. Buchstaben pro Seite    
    
preg_match_all("/.{0,$bps}.+?\W/s", $text, $seiten);
    
$seite = intval($_GET['seite']);
if ($seite < 1 || $seite > count($seiten[0]))
    $seite = 1;

echo $seiten[0][$seite-1];  
if ($seite > 1)
    echo "<a href='page_reader.php?seite=".($seite-1)."'>Vorherige Seite</a>&nbsp;";
echo "<b>Seite $seite</b>&nbsp;";
if ($seite < count($seiten[0]))
    echo "<a href='page_reader.php?seite=".($seite+1)."'>Nächste Seite</a>&nbsp;";

Ich weiss nicht genau wie ich die variablen verketten soll... Könnte mir jemand helfen? Den Fehler zeigen? Codevorschläge?
Vielen Dank im Voraus
 
Hi und Willkommen bei tutorials.de

da, wo du mit fgets zeilenweise einliest
überschreibst du jeweils die vorher eingelesene Zeile.
Am Schluss hast du nur den Inhalt der letzten Zeile in der Variable
(vermutlich ein einsamer Zeilenwechsel, den man nicht sieht).

Entweder setzt du die Variable am Anfang auf einen leeren String ""
und hängst in der Schleife immer die aktuelle Zeile ans Ende an, statt ganz zu ersetzen
( .= statt = )

Oder man spart sich die ganze Einleseschleife samt Öffnen und Schließen,
weil die Funktion file() mit einem Aufruf eine ganze Datei (in ein Array aus Zeilen/Strings) einliest
 
:rolleyes:
php.de ist bekannt für sowas.
Hier wird zwar auch ab und zu gesagt, sich doch selbst anzustrengen
(vor allem bei Fragen,über die man ganze Bücher schreiben kann)
aber das...

Was das Crossposting angeht, das ist hier nicht verboten.
User nicht fangen, sondern helfen...
 
Und wenn du den ganzen Text auf einmal einlesen willst, ohne umweg über Arrays oder schleifen

file_get_contents()
 
Wer weiß wie lang die Texte sind. Da würde ich im Sinne des RAM (auch wenn der Server richtig viel hat), lieber folgendes Konstrukt aufbauen:

PHP:
// handle zu datei aufbauen
// $fh = fopen

// leere Ausgabe als Puffer
$out = '';

// prüfen ob alter pointer vorhanden (aus session oder $_GET)
{ // alter pointer vorhanden: gehe zu der stelle
  // $pointer = ...
  fseek($pointer);
}


// solange nicht das ende der Datei
{
  // lies eine Zeile
  // $line = fgets
  // prüfe ob seitenende mit dieser zeile erreicht
  { // seitenende erreicht: abschneiden und ausgeben
    // zeile dort abschneiden, wo die seite es nicht mehr anzeigen kann
    // pointer der datei merken (in session oder in links verarbeiten)
    // $pointer = ...
    // alles ausgeben
    echo $out;
  }
  else
  { // seitenende durch die zeile nicht erreicht: füge hinzu
    $out .= $line;
  }
}

Btw: So schreibe ich mittlerweile meistens Programme einmal runter. Nur Kommentare und danach den Code. Auf der einen Seite sehe ich die Logik vorher und erkenne evtl. Denkfehler. Auf der anderen ist der Code immer schön dokumentiert ;)
 
Auf der anderen ist der Code immer schön dokumentiert

Na ja… Viele Codezeilen sind nun wirklich selbsterklärend.

Die Idee ist ansonsten nicht schlecht, aber die grundsätzliche Schwierigkeit bleibt das Blättern, vor allem das Zurückblättern.

Das wird dann offensichtlich, wenn wir Multibyte-Zeichensätze voraussetzen oder wenn wir berücksichtigen, dass Wörter/Sätze nicht abgeschnitten werden sollen.

Edit: Das sind übrigens Hintergründe, die der Threadersteller optimalerweise genauer beschreiben sollte.
 
Zuletzt bearbeitet:
Danke an den Moderator. Habe den Fehler gefunden. Habe den Punkt vergessen - Der Code klappt nun vorerst:

$text .= fgets($fp);
echo $text;


Trotzdem würde mich die Vorgehensweise von Zodiac interessieren. Kurz das Zitat:

Wer weiß wie lang die Texte sind. Da würde ich im Sinne des RAM (auch wenn der Server richtig viel hat), lieber folgendes Konstrukt aufbauen:

PHP:
// handle zu datei aufbauen
// $fh = fopen

.. (gekürzt) ..

  }
}

Btw: So schreibe ich mittlerweile meistens Programme einmal runter. Nur Kommentare und danach den Code. Auf der einen Seite sehe ich die Logik vorher und erkenne evtl. Denkfehler. Auf der anderen ist der Code immer schön dokumentiert ;)

Ich hab mich jetzt durchgearbeitet und versucht das ganze sinvoll umzusetzten. Habe jedoch ein(ige ?) Fehler bei der Umsetzung gemacht. Unklar war mir die Variable $out und $line, bzw. der Umgang mit ihnen. Möglicherweise habe ich auch die if-Klammern falsch gesetzt? Nach einigem Ausprobieren ist dies meine wohl oder übel beste (falsche) Version des Codes:

~ Was ist falsch? Oder wo soll ich noch was Abändern, wie?
PHP:
$fh = fopen("http://www.ir.pcklick.net/creativ/history/45345btt.txt","r");
$out = '';


if (isset($pointer)) {
        fseek($pointer); 
        
} 
if ($pointer > "0") {
        
    if ($line = fgets($fh) > "0") {
    $pointer = $_SESSION['pointer'] = $line;
    echo $out;
} } else {
    $out .= $line; }
    


$fh = fopen("data.txt","r");
$out = '';


if (isset($pointer)) {
        fseek($pointer); 
        
} 
if ($pointer > "0") {
        
    if ($line = fgets($fh) > "0") {
    $pointer = $_SESSION['pointer'] = $line;
    echo $out;
} } else {
    $out .= $line; }
    
    
echo $out;
$bps = 20; // min. Buchstaben pro Seite    
    
preg_match_all("/.{0,$bps}.+?\W/s", $out, $seiten);
    
$seite = intval($_GET['seite']);
if ($seite < 1 || $seite > count($seiten[0]))
    $seite = 1;

echo $seiten[0][$seite-1];  
if ($seite > 1)
    echo "<a href='page_reader.php?seite=".($seite-1)."'>Vorherige Seite</a>&nbsp;";
echo "<b>Seite $seite</b>&nbsp;";
if ($seite < count($seiten[0]))
    echo "<a href='page_reader.php?seite=".($seite+1)."'>Nächste Seite</a>&nbsp;";

Übrigens vielen Dank für das Verständnis in diesem Forum. In dem obrig erwähnten Forum hatte man mich aufgrund meines Unwissens nur beschimpft und keine gute Ratschläge wie diesen (Zitat) abgegeben.

LG Tarek aka pcklick :D
 
Zuletzt bearbeitet:
Danke an den Moderator. Habe den Fehler gefunden. Habe den Punkt vergessen

Man hat auf php.de 16 Beiträge lang versucht, dir das zu vermitteln. Die Leute haben dich nicht mit der Nase drauf gestoßen, aber sie haben deine Nase zumindest bis auf 2 cm Entfernung dran gedrückt.

Dass du das dann nicht selbst merkst, kann niemand ahnen. Vor allem nicht, wenn man davon ausgeht, dass du der Autor des Codes bist.

Übrigens vielen Dank für das Verständnis in diesem Forum. In dem obrig erwähnten Forum hatte man mich aufgrund meines Unwissens nur beschimpft und keine gute Ratschläge wie diesen (Zitat) abgegeben.

Das soll im Zweifel bitte jeder für sich entscheiden. Der Link steht ja oben.

~ Was ist falsch? Oder wo soll ich noch was Abändern, wie?

Ich meine das nicht böse, aber es ist meines Erachtens schwierig, dir zu helfen, weil sich überhaupt nicht einschätzen lässt, was du an Wissen hast oder was du verstehen oder nachvollziehen kannst.

Du hast da etwa auf der einen Seite einen regulären Ausdruck stehen (preg_match_all("/.{0,$bps}.+?\W/s", $out, $seiten);), scheiterst aber andererseits daran, simplen Dateizugriff oder Stringverkettungen durchzuführen.

Ich vermute, du weißt nicht, was der reguläre Ausdruck macht, denn sonst wärst du wahrscheinlich auf meinen letzten Post eingegangen.

Der fseek-Ansatz wird mit einer trivialen Implementierung nicht funktionieren, wenn du rückwärts blättern willst und Multibyte-Zeichensätze hast oder Logik willst, wie sie etwa im regulären Ausdruck steht. Da braucht es mehr Funktionalität, und ich weiß nicht, ob du mit entsprechendem Code viel anfangen könntest, weil du gewissermaßen schon das Problem nicht zu sehen scheinst, obwohl du (?) Code geschrieben hast, der sich damit befasst.

PS: Würde es eine simple Lösung geben, hätte ich die gepostet. Hier sind halt bereits die genauen Anforderungen unklar.
 
Zuletzt bearbeitet:
Zurück