bonehunter: Source von PERL > PHP

Hallo Selfforum,

ich hab ein Problem.

Ich hab einer Bekannten versprochen, ihr ein Script von Perl nach PHP umzuwandeln. Ich hab jetzt eigentlich das meiste geschaft, bis auf einen Kleinen Teil.

Das Script um das es geht ist eine interaktive Geschichte, bei der die Besucher mitschreiben können. Die Geschichte hat einen gemeinsamen Anfang(kapitel 1) und zwei antwortmöglichkeuten. Zu jeder dieser Antwortmäöglichkeiten kann jetzt der Besucher eine fortführung der Geschichte (Kapitel 2) mit weiteren 2 Antwortmöglichkeiten schreiben usw.

Jetzt gibt es für diese Geschichte auch eine Kapitelübersicht die ungefähr so aussieht:

Kapitel 1
  Kapitel 2
    Kapitel 3
     Kapitel 4
       Kapitel 5
     Kapitel 4
    Kapitel 3
     Kapitel 4
     Kapitel 4
  Kapitel 2
    Kapitel 3
     Kapitel 4
     Kapitel 4
    Kapitel 3
     Kapitel 4
     Kapitel 4
.....

Und daran verzweifle ich. Ich verstehe das einfach nicht und kann es also auch nicht in PHP umsetzen. Bitte helft mir dabei, ich möchte icht, dass die ganze Arbeit bisher umsonst war. Kenne mich leider nicht besonders gut in Perl aus.

Hier noch der Quelltext:

outline_tree(1, 1);

sub outline_tree {
   if (-e "$story_dir/$_[0].txt") {

$auth = "";
      $title = "";
      $time = "";

if (open(CHAPTER, "$story_dir/$_[0].txt")) {
         $auth = <CHAPTER>;
  $time = <CHAPTER>;
  $title = <CHAPTER>;
         close(CHAPTER);

chomp($auth);
         chomp($title);
         chomp($time);
         if ($auth ne "") {
            $auth = "von $auth";
         }
      }

print "   " x ($_[1] - 1);
      $x = format_chapter_number($_[1] - 1);
      print "Kapitel $_[1]: <a href="story.pl?next=$_[0]&chapter=$x">$title</a> $auth";

outline_tree(2 * $_[0], $_[1] + 1);
      outline_tree((2 * $_[0]) + 1, $_[1] + 1);

$chapter_count++
   }
}

sub format_chapter_number {
   my $my_chapter_number = $_[0];   # Parameter is chapter number.
   return(sprintf("%.0f", $my_chapter_number));
}

mfg bonehunter

  1. Moin!

    outline_tree(1, 1);

    Aufruf einer Funktion.

    sub outline_tree {

    # das ist die Funktion. Du kannst diese mit "sub" -> "function (arg1, arg2,...)" um"schreiben".

    if (-e "$story_dir/$_[0].txt") {

    # $_[0] ist das erste Argument der Argumenteliste.
          # Existiert die Datei $story_dir/$_[0].txt ?
          # Du brauchst $story_dir als globale Variable oder mussr es übergeben.

    $auth = "";
          $title = "";
          $time = "";

    # Kein Kommentar.

    if (open(CHAPTER, "$story_dir/$_[0].txt")) {

    # CHAPTER wird ein Filehandler , das weitere geschieht, so das Öffnen gelingt.

    $auth = <CHAPTER>;
             $time = <CHAPTER>;
             $title = <CHAPTER>;
             close(CHAPTER);

    # Die   Variablen werden mit dem Inhalt der Zeilen von $story_dir/$_[0].txt gefüllt

    chomp($auth);
             chomp($title);
             chomp($time);
             if ($auth ne "") {
                $auth = "von $auth";
             } # end if
          } # end if

    # Die Variablen wurden ein wenig "fein" gemacht.

    print "   " x ($_[1] - 1);
          $x = format_chapter_number($_[1] - 1);
          print "Kapitel $_[1]: <a href="story.pl?next=$_[0]&chapter=$x">$title</a> $auth";

    # Es ein wenig was ausgegeben.

    # Es folgt ein rekursiver Funktionsaufruf (Funktion ruft sich selbst)

    # Dazu wird das erste Argument verdoppelt, das zweite um eines erhöht.

    outline_tree(2 * $_[0], $_[1] + 1);

    # Da es immer zwei Möglichkeiten der Fortsetzung gibt:
             # Das erste Argument wird verdoppelt und um eines erhöht, das zweite um eines erhöht

    outline_tree((2 * $_[0]) + 1, $_[1] + 1);

    $chapter_count++

    # Die offenbar globale Variable chapter_count wir um eines erhöht.

    } end if
    } end function

    sub format_chapter_number {
       my $my_chapter_number = $_[0];   # Parameter is chapter number.
       return(sprintf("%.0f", $my_chapter_number));

    # Ganz tolle Funktion.  Gibt den übergebenen Wert als ganze Tahl zurück.
          # ein "$my_chapter_number=$my_chapter_number*1" hätte das auch getan...

    } end function

    MFFG (Mit freundlich- friedfertigem Grinsen)

    fastix®

    --
    Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Development. Auch  für seriöse Agenturen.
    1. Hallo fastix®,
      Hallo Selfforum,

      danke für deine Antwort und die Erklärungen zum Perl-Quelltext.

      Ich denke, dass ich den Perl-Quelltext jetzt verstanden habe.

      Alle Teile der Geschichte werden als .txt-Dateien im selben Verzeichnis gespeichert. Der Dateiname ist immer die nummer der Geschichte. Also heißt die erste geschichte logischerweise 1.txt

      Ich habe mal versucht den Perl-Quelltext in PHP umzusetzten.
      das ist mir wohl zum Teil auch gelungen, es fehlt nur noch die richtige Sortierung.

      Ich versuche das mal am Beispiel zu erklären:
      Wenn wir also eine kleine Geschichte mit 8 Teilen haben, sollte das so aussehen:

      Kapitel 1 -> 1.txt
        Kapitel 2 -> 2.txt
          Kapitel 3 -> 4.txt
          Kapitel 3 -> 5.txt
            Kapitel 4 -> 10.txt
        Kapitel 2 -> 3.txt
          Kapitel 3 -> 6.txt
            Kapitel 4 -> 12.txt

      Es siehst aber momentan so aus:
      Kapitel 1 -> 1.txt
            Kapitel 4 -> 10.txt
            Kapitel 4 -> 12.txt
        Kapitel 2 -> 2.txt
        Kapitel 2 -> 3.txt
          Kapitel 3 -> 4.txt
          Kapitel 3 -> 5.txt
          Kapitel 3 -> 6.txt

      Die Sortierung entspricht momentan noch der wie sie im Verzeichnis ausgelesen wurde, also nach dem Dateiname absteigend.

      Hier mein neuer PHP-Quelltext. Kannst du (könnt ihr) mir helfen das mit der Sortierung hinzubekommen?

      echo "<b>Überblick über die Geschichte:</b><br>\n";

      // liest alle vorhandenen Dateien aus dem Verzeichnis aus
      $handle = @opendir("story/");
      while ($file = @readdir ($handle))
      {
          //.txt vom String entfernen ($next)
          $rest = substr($file, 0, -4);
          $next = $rest;

      //Berechnung des Kapitels ($chapter)
          $chapter = "0";
          while($rest >= 1)
          {
              if ($rest % 2 != 0)
              {
                  $rest = $rest - 1;
              }
              $rest = $rest / 2;
              $chapter++;
          }

      $datei = "/web/stuff/story/$next.txt";

      $array = file($datei);

      //Einrückung entsprechend Kapitel
          $margin = $chapter * 10;

      echo "<spanstyle="marginleft: ".$margin."px;">Kapitel$chapter: <a href="story.php$next&chapter=$chapter">$array[2]</a> $array[0]<br></span>";
      }
      @closedir($handle);

      mfg bonehunter

      1. Hallo,

        ich dachte ich frag jetzt mal nach, worum bisher niemand geantwortet hat. Bin eben ein ungeduldiger Mensch.

        Ist das Problem zu schwer?
        Habt ihr keine Lust?
        Hab ich es falsch oder schlecht erklärt?

        mfg bonehunter

        1. Moin!

          Die Antwort ist, da das Problem gelöst ist, nunmehr für das Archiv....

          Ist das Problem zu schwer?

          Nein, aber "umfangreich". Die Antwort zu verfassen kann schon mal allein eine Stunde dauern...

          Habt ihr keine Lust?

          Du hast die Frage am frühen Nachmittag gestellt. Viele haben einen Job... oder sind Sonntags auch mal mit was anderem beschäftigt. Und niemand "arbeitet" hier als "Beantworter". Aber keine Angst. Hier rutschen Fragen selten unbeantwortet durch. Einige hier suchen direkt nach schwierigeren Fragen, wohl um sich selber auch mal Lernaufgaben zu stellen oder als Finder einer schwierigeren Lösung zu "glänzen".

          Es war aber absolut richtig von Dir nochmals nachzuhaken- damit gesehen werden konnte, daß es noch Probleme gibt.

          Hab ich es falsch oder schlecht erklärt?

          Nein, daran lag es nicht. Wäre es das gewesen, dann bekämst Du, meiner Erfahrung nach, eine entsprechende Nachfrage.

          MFFG (Mit freundlich- friedfertigem Grinsen)

          fastix®

          --
          Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Development. Auch  für seriöse Agenturen.
          1. Hallo fastix,

            danke nochmal für deine Antwort.

            mfg bonehunter

    2. Hallo fastix,

      ich habs hinbekommen, deine Tips haben es mir ermöglicht.

      hier noch kurz die Lösung, fals es dich interessiert:

      echo "<b>Überblick über die Geschichte:</b><br>\n";

      function outline($next, $chapter)
       {
        $datei = "/web/stuff/story/$next.txt";

      //Wenn Kapitel vorhanden
        if (file_exists($datei))
        {
         //Datei in Array einlesen
         $array = file($datei);

      //Einrückung entsprechend Kapitel
         $margin = ($chapter-1) * 10;

      //Ausgabe des Links
         echo "<span style="margin-left: ".$margin."px;">Kapitel $chapter: <a href="story.php?next=$next&chapter=$chapter">$array[2]</a> $array[0]<br></span>";

      //Rekursiver Funktionsaufruf (Funktion ruft sich selbst) - beide Möglichkeiten
         outline($next*2, $chapter+1);
         outline(($next*2)+1, $chapter+1);
        }
       }

      outline(1, 1);

      War eigentlich gar nicht so schwer wie ich dachte, bin am Anfang nur total am Ziel vorbeigeschossen, dann hab ich mir nochmal deine Kommentare durchgelesen und "Rekursiver Funktionsaufruf (Funktion ruft sich selbst)" hat mich dann auf den richtigen Weg gebracht. 2 Minuten später hats funkioniert. Super, danke.

      mfg bonehunter