Hausi

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Hausi

    Hallo vielleicht kann mir jemand helfen: mache gerade einen PHP Kurs und hänge schon ewig mit einer Aufgabe rum. Ein Formular drei Felder soll eingelesen werden aber bei mir werden die Felder nicht korrekt und nicht durchgängig beschrieben.

    das ist das Forum:

    PHP-Code:
    <?php
    require_once ("forumsfunktionen5.php");
    ?>
    <html>
      <head><title>Forum</title></head>
      <body>
        <h1>Willkommen beim Forum</h1>
    <?php formular_ausgeben(); ?>
        <hr />
    <?php
      
    for ($i count($beitraege)-1$i >= 0$i--)
      {
      
    $nr $i +1;
      echo 
    "Nr: ".$nr."<br>";
        
    beitrag_ausgeben($beitraege[$i]);
        print 
    "<hr>\n";
      }
    ?>
        <p>Thats all folks.</p>
      </body>
    </html>

    und das ist die zugehörige Datei:
    <?php
    $beitraege 
    = array();
    beitrag_schreiben();
    beitraege_einlesen();

    function 
    beitrag_schreiben($datei "beitraege.txt")
    {
      if (!empty(
    $_REQUEST['text']))
      {
        
    $dh fopen($datei"a");
        if (!
    $dh)
        {
          print 
    "Kann Datei nicht erstellen!\n";
        }
        else
        {
          
    $neuertext trim($_REQUEST["text"]);
          
    $neuertext str_replace("\n"""$_REQUEST);
          if (!empty(
    $_REQUEST['betreff']))
            {
            
    fputs($dh$_REQUEST['betreff']."\n");
            }
          else
            {
            
    fputs($dh"kein Betreff\n");
            
    fputs($dh$neuertext."\n");
              if (!empty(
    $_REQUEST['autor']))
              {
              
    fputs ($dh$_REQUEST['autor']."\n");
              }
              else
              {
              
    fputs ($dh"unbekannt\n");
              }
              
    fclose ($dh);
            }
      }
    }
    }
    function 
    beitraege_einlesen($datei "beitraege.txt")
    {
      global 
    $beitraege;

      
    $dh fopen($datei"r");
      if(!
    $dh)
      {
        print 
    "Kann Datei \"$datei\" nicht &ouml;ffnen!\n";
      }
      else
      {
        for (
    $i 0; !feof($dh); $i++)
        {
          
    $zeile fgets($dh);
          if (
    $zeile != "")
          {
            
    $beitraege[$i]['text'] = fgets($dh);
            
    $beitraege[$i]['autor'] = fgets($dh);
            
    $beitraege[$i]['betreff'] = $zeile
          }
        }
        
    fclose($dh);
      }
    }

    function 
    beitrag_ausgeben($beitrag)
    {
        print 
    "<strong>Betreff: ".$beitrag['betreff']."</strong>\n";
        print 
    "<br>";
        print 
    "Eintrag: ".$beitrag['text']."\n";
        print 
    "<br>";
        print 
    "Autor: ".$beitrag['autor']."\n";
    }

    function 
    formular_ausgeben()
    {
    ?>
          <form method="POST" action="<?php print $_SERVER['PHP_SELF'?>">
            <b>Betreff: </b><input name="betreff" type="text" />
            <br /> <br />
            <b>Eintrag: </b><textarea type="text" name="text" cols="50" rows="10      style="overflow:hidden"></textarea>
            <br /> <br />
            <b>Autor: </b><input type="text" name="autor">
            <br /> <br />
            <input type="submit" value="absenden">
          </form>
    <?php
    }
    ?>
    Zuletzt geändert von admin; 13.03.2014, 14:55.

  • #2
    Hallo Ups,

    ich habe mir deinen Quelltext einmal angesehen und habe dabei das ein oder andere Problem gefunden und behoben.
    Hier eine kurze Zusammenfassung:
    • Die Formular-Eingabe habe ich aus der externen PHP rausgenommen und wieder in die eigentliche HTML Datei eingefügt. Warum? Weil das im vorliegenden Quelltext sinnvoller ist.
    • Ich habe die meisten HTML-Fehler behoben. (Doctype, Encoding etc.) Das Dokument wird mir nun als gültiges HTML5 angezeigt.
    • Einige Syntax-Fehler sind behoben.
    • Eigentlich hab ich den PHP-Anteil komplett neu geschrieben und mit Kommentaren versehen.

    Hier mal die beiden neuen Dateien:
    forum_functions.php
    PHP-Code:
    <?php
        
    /**
         * Speichert einen neuen Eintrag in die Datei.
         *
         * @param string $aTopic Betreff der Eitnrages
         * @param string $aMessage Die eigentliche Nachricht
         * @param string $aAuthor Der Verfasser der Nachricht
         * @param string $aFile [OPTIONAL] Pfad und Namde der Text-Datei in die der Eintrag geschrieben werden soll
         *
         * @return bool Gibt an, ob der Eintrag erfolgreich geschrieben werden konnte
         */
        
    function addEntry$aTopic$aMessage$aAuthor$aFile "beitraege.txt" ) {
            
    // Variablen entgegen nehmen und ggf. bearbeiten
            
    $lTopic $aTopic;
            
    $lAuthor $aAuthor;
            
    $lMessage str_replace"\n"""nl2brtrim$aMessage ) ) );
            
    $lFile $aFile;

            
    // Versuchen die Datei fuer schreibzugriff zu oeffnen
            
    $lFileHandle fopen$lFile"a" );

            if ( !
    $lFileHandle ) {
                return 
    false;
            }

            
    // Eintraege schreiben
            
    fwrite$lFileHandle$lTopic."\n"   );
            
    fwrite$lFileHandle$lAuthor."\n"  );
            
    fwrite$lFileHandle$lMessage."\n" );

            
    // Hat VERMUTLICH geklappt ...
            
    return true;
        }

        
    /**
         * Liest alle Eintraege aus der angegebenen Text-Datei.
         *
         * @param string $aFile [OPTIONAL] Pfad und Name der Text-Datei die ausgelesen werden soll
         *
         * @return mixed Gibt ein array mit allen Eintraegen zuruck. Im Fehlerfall wird FALSE zurueckgegeben.
         */
        
    function getEntries $aFile "beitraege.txt" ) {
            
    $lEntries = array();

            
    // Gibt es die Datei ueberhaupt?
            
    if ( !file_exists$aFile ) ) {
                return 
    false;
            }

            
    // Besteht Lese-Zugriff auf die Datei?
            
    if ( !is_readable$aFile ) ) {
                return 
    false;
            }

            
    // Versuchen, die Datei zu oeffnen
            
    $lFileHandle fopen$aFile"r" );
            if ( !
    $lFileHandle ) {
                return 
    false;
            }

            
    // Zeilen durchgehen, bis das Ende der Datei erreicht wurde
            
    while ( !feof$lFileHandle ) ) {
                
    $lTopic   fgets$lFileHandle );
                
    $lAuthor  fgets$lFileHandle );
                
    $lMessage fgets$lFileHandle );

                
    // Eintrag im Array ablegen, sofern dieser nicht leer ist
                
    if ( !empty(trim($lTopic)) && !empty(trim($lAuthor)) && !empty(trim($lMessage)) ) {
                    
    $lEntries[] = array(
                        
    "topic" => $lTopic,
                        
    "author" => $lAuthor,
                        
    "message" => $lMessage
                    
    );
                }
            }

            
    // Zu guter Letzt die Datei wieder freigeben
            
    fclose$lFileHandle );

            
    // Fertiges array zurueckgeben
            
    return $lEntries;
        }
    ?>
    Und hier die neue forum.php
    PHP-Code:
    <?php
        
    // Funktionen zum Lesen und Schreiben einbinden
        
    require_once( "forum_functions.php" );

        
    // Wurde versucht, ein Eitnrag zu hinterlassen?
        
    $AddEntryError false;
        if ( 
    strtoupper$_SERVER["REQUEST_METHOD"] ) === "POST" ) {
            
    // Variablen entgegen nehmen
            
    $Topic   filter_inputINPUT_POST"topic"  FILTER_SANITIZE_STRING );
            
    $Author  filter_inputINPUT_POST"author" FILTER_SANITIZE_STRING );
            
    $Message filter_inputINPUT_POST"message"FILTER_SANITIZE_STRING );

            
    // Pruefen ob alle Variablen vorhanden 8und gueltig) sind
            
    if ( (is_string($Topic)) && (is_string($Author)) && (is_string($Message)) ) {
                
    // Jopp, VERSUCHEN, die Daten zu schreiben
                
    $AddEntryError = !addEntry$Topic $Message$Author );
            }
        }

        
    // VERSUCHEN, die Eintraege auszulesen
        
    $Entries getEntries();
    ?>
    <!doctype html>
     <html>
        <head>
            <title>Forum</title>
            <meta charset="utf-8">
        </head>
        <body>
            <h1>Willkommen beim Forum</h1>
    <?php if ( $AddEntryError ) { echo "Fehler beim Schreiben der Daten!"; } ?>
            <form method="POST">
                <b>Betreff: </b><input name="topic" type="text" required="required" />
                <br /> <br />
                <b>Eintrag: </b><textarea required="required" name="message" cols="50" rows="10" style="overflow:hidden"></textarea>
                <br />
                <br />
                <b>Autor: </b><input type="text" name="author" required="required">
                <br />
                <br />
                <input type="submit" value="absenden">
            </form>
            <hr />
            <!-- Bisherige Eintraege anzeigen lassen -->
    <?php
            
    if (is_array$Entries ) ) {
                foreach ( 
    $Entries as $CurrentEntry ) {
    ?>
            <h3><?php echo $CurrentEntry["topic"?> von <?php echo $CurrentEntry["author"?></h3>
            <p>
                <?php echo $CurrentEntry"message" ]; ?>
            </p>
    <?php
                
    }
            } else {
    ?>
            <p>
                Keine Eintr&auml;ge vorhanden.
            </p>

    <?php
            
    }
    ?>
        </body>
    </html>
    Ich hoffe, das hilft dir ein wenig weiter. Bei Fragen, einfach hier posten. Ich antworte so früh ich kann (was demnächst eine Weile dauern kann).

    Gruß
    ~ Chris

    Kommentar


    • #3
      Danke aber ...

      Hey Chris
      das sieht wirklich super aus und ehrlich gesagt viel logischer als meine Vorgaben - und ich frage lieber nicht wieviel Zeit Du gebraucht hast dafür - nur würde ich gerne meinen Fehler finden im bestehenden Script. Es sind leider ja noch nicht so viele Befehle in Anwendung aber steter Tropfen höhlt den Stein.

      Kommentar


      • #4
        Hallo Chris

        Dein Script gibt diesen Fehlerhinweis ...
        Fatal error: Can't use function return value in write context in C:\xampp\htdocs\Forum_functions.php on line 68
        STephan

        Kommentar


        • #5
          empty nimmt vor PHP Version 5.5.0 nur Variablen als Parameter an – also ist das entsprechend anzupassen, wenn du eine ältere PHP-Version nutzt.
          I don't believe in rebirth. Actually, I never did in my whole lives.

          Kommentar


          • #6
            Hallo,

            gute Einstellung.
            Es freut mich zu sehen, dass du gerne wissen möchtest was genau schief läuft.
            Ich poste nochmal deinen Quelltext. Aber ich füge Zeilennummern hinzu. Und dann zeige ich dir, welche Zeilen Fehler enthalten oder ungünstig sind. Und auch, wie du es besser machen oder die Fehler komplett beheben kannst.

            PHP-Code:
            01 <?php
            02     
            require_once ("forumsfunktionen5.php");
            03 ?>
            04 <html>
            05     <head><title>Forum</title></head>
            06     <body>
            07         <h1>Willkommen beim Forum</h1>
            08 <?php formular_ausgeben(); ?>
            09     <hr />
            10 <?php
            11   
            for ($i count($beitraege)-1$i >= 0$i--)
            12   {
            13   $nr $i +1;
            14   echo "Nr: ".$nr."<br>";
            15     beitrag_ausgeben($beitraege[$i]);
            16     print "<hr>\n";
            17   }
            18 ?>
            19     <p>Thats all folks.</p>
            20   </body>
            21 </html>
            Zeile 8:
            Du verwendest PHP hier einzig um eine Funktion aufzurufen, die wiederrum nur HTML anzeigt. Das ist recht überflüssig und sorgt nur für Verwirrung. Es ist sinnvoller den HTML-Anteil einfach dort hinzuschreiben und die Funktion ersatzlos zu streichen.

            Zeile 11:
            Anders als z.B. JavaScript bietet PHP eine Schleife speziell für Arrays an. Sie nennt sich foreach. So musst du das Array nicht manuell mit einem Index durchlaufen.

            Zeile 14 & 16:
            Du verwendest print und echo. Das ist an sich zwar kein Problem. Aber man sollte sich innerhalb einer Anwedung für eine der beiden Varianten entscheiden.


            Nun zu deinem PHP-Teil:
            PHP-Code:
            01 <?php
            02 $beitraege 
            = array();
            03 beitrag_schreiben();
            04 beitraege_einlesen();
            05 
            06 
            function beitrag_schreiben($datei "beitraege.txt")
            07 {
            08   if (!empty($_REQUEST['text']))
            09   {
            10     $dh fopen($datei"a");
            11     if (!$dh)
            12     {
            13       print "Kann Datei nicht erstellen!\n";
            14     }
            15     else
            16     {
            17       $neuertext trim($_REQUEST["text"]);
            18       $neuertext str_replace("\n"""$_REQUEST);
            19       if (!empty($_REQUEST['betreff']))
            20         {
            21         fputs($dh$_REQUEST['betreff']."\n");
            22         }
            23       else
            24         {
            25         fputs($dh"kein Betreff\n");
            26         fputs($dh$neuertext."\n");
            27           if (!empty($_REQUEST['autor']))
            28           {
            29           fputs ($dh$_REQUEST['autor']."\n");
            30           }
            31           else
            32           {
            33           fputs ($dh"unbekannt\n");
            34           }
            35           fclose ($dh);
            36         }
            37   }
            38  }
            39 }
            40 function beitraege_einlesen($datei "beitraege.txt")
            41 {
            42   global $beitraege;
            43 
            44   $dh 
            fopen($datei"r");
            45   if(!$dh)
            46   {
            47     print "Kann Datei \"$datei\" nicht &ouml;ffnen!\n";
            48   }
            49   else
            50   {
            51     for ($i 0; !feof($dh); $i++)
            52     {
            53       $zeile fgets($dh);
            54       if ($zeile != "")
            55       {
            56         $beitraege[$i]['text'] = fgets($dh);
            57         $beitraege[$i]['autor'] = fgets($dh);
            58         $beitraege[$i]['betreff'] = $zeile
            59       }
            60     }
            61     fclose($dh);
            62   }
            63 }
            64  
            65 
            function beitrag_ausgeben($beitrag)
            66 {
            67     print "<strong>Betreff: ".$beitrag['betreff']."</strong>\n";
            68     print "<br>";
            69     print "Eintrag: ".$beitrag['text']."\n";
            70     print "<br>";
            71     print "Autor: ".$beitrag['autor']."\n";
            72 }
            73 
            74 
            function formular_ausgeben()
            75 {
            76 ?>
            77       <form method="POST" action="<?php print $_SERVER['PHP_SELF'?>">
            78         <b>Betreff: </b><input name="betreff" type="text" />
            79         <br /> <br />
            80         <b>Eintrag: </b><textarea type="text" name="text" cols="50" rows="10      style="overflow:hidden"></textarea>
            81         <br /> <br />
            82         <b>Autor: </b><input type="text" name="autor">
            83         <br /> <br />
            84         <input type="submit" value="absenden">
            85       </form>
            86 <?php
            87 
            }
            88 ?>
            Zeile 8:
            Du verwendest hier die Superglobale $_REQUEST. Guter Rat von mir: Mach das nicht. Verlasse dich nicht auf $_REQUEST sondern verwende lieber $_GET oder $_POST. Ansonsten können die Daten sonstwo her kommen. Absolut unsicher und definitiv nicht vertrauenswürdig. Sollte dein Lehrer anderer Meinung sein, frag ihn bitte ob er den richtigen Beruf hat.
            Zudem prüfst du nicht, auf welche Weise die Daten bei dir angelangen. Stell VORHER sicher, dass der "Request"-Mode korrekt ist. Das kannst du mit einem einfachen $_SERVER[ "REQUEST_METHOD" ] prüfen. Dort steht dann für gewöhnlich "GET" oder "POST". Das Formular verwendet "POST". Und daher sollte die Funktion auch nur weitermachen, wenn es tatsächlich im POST-Modus ist.
            Denn so wie das derzeit ist, versucht das Skript IMMER zu schreiben. Es reicht schon, wenn man mit GET-Parametern spielt.
            Und noch eine Anmerkung zu Zeile 8: Du prüfst nur, ob die Variable leer ist. Nicht aber, ob es sie überhaupt gibt. Das ist bei kleineren Projekten, die nie in den Produktiven Einsatz gehen noch okay sein. Später solltest du aber auch prüfen ob es die Variable überhaupt gibt. Entweder durch die isset() Funktion oder - was ein wenig eleganter ist - durch die filter_input() Funktion.

            Zeile 8, Zeile 11 und Zeile 15:
            Das was nun folgt, ist nicht wirklich falsch. Sondern eher ein Ratschlag. Versuch den Ablauf nicht tiefer zu verschachteln als nötig. Verschachtelte if ... else ... kann man für gewöhnlich anders herum besser lösen.
            Anstatt also
            PHP-Code:
                if (!$dh)
                {
                  print 
            "Kann Datei nicht erstellen!\n";
                }
                else
                {
                  
            $neuertext trim($_REQUEST["text"]); 
            wäre folgendes eleganter und übersichtlicher:
            PHP-Code:
                if (!$dh)
                {
                  return;
                }

                
            $neuertext trim($_REQUEST["text"]); 
            Auf dem ersten Blick ist der Untschied nicht groß. Aber je tiefer du das verschachtelst, destor größer der Unterschied.

            Zeile 25, 26 etc.:
            Die Verwendung von fputs ist zwar nicht falsch - und wenn man an fgets denkt auch nicht weit hergeholt - es empfiehlt sich aber, keine Aliase anderer Funktionen zu benutzen. Und genau das ist fputs. Ein Alias für fwrite.

            Zeile 42:
            Arbeite lieber nicht mit globalen Variablen. Leg lieber ein Array an, das du nur für die aktuelle Funktion verwendest. Dieses gibst du dann am Ende zurück. Der Aufruf der Funktion wäre dann in etwa so:
            PHP-Code:
                $Beitraege beitraege_einlesen(); 
            Der Aufwand ist nicht - oder nur sehr geringfügig - höher als vorher. Es steigert jedoch die Lesbarkeit und beugt Fehler durch falschen Zugriff vor.

            Zeile 77:
            Das action="..." kannst du dir sparen. Sofern du keine Seite für Action angibst, wird automatisch die Seite aufgerufen, die das Formular abgeschickt hat. Und das ist "rein zufällig" die gleiche Datei die du druch PHP_SELF ausgibst.

            Zeile 80:
            Kleiner Fehler im HTML: Du hast die ROWs nicht geschlossen, was zu bugs führen kann.

            Ooookay ... Das hat jetzt länger gedauert als das Skript neu zu schreiben.

            Ich hoffe, das hilft dir dennoch ein wenig weiter.
            Gruß
            ~ Chris

            // EDIT: Ich wusste nicht, dass die Funktion empty nur Variablen als Parameter annimmt. Ich verwende PHP 5.5.6 (XAMPP 1.8.3) zum Testen. Danke das du darauf hingewiesen hast, wahsaga.
            Zuletzt geändert von anihex; 15.03.2014, 20:24.

            Kommentar


            • #7
              Danke

              Hallo Chris

              nochmals vielen Dank - habe schon verschiedentlich gehört, das was ich da lerne ist wohl veraltet. Da ist es toll Deine Koorekturen anzuprobieren.
              Aber nach wie vor liesst der mir die Daten nicht ins Feld noch in die Textdatei korrekt. Z.Zt. wird immer nur ein Feld beschrieben, keine Ahnung warum ... . Wenn ich nur im Feld Text eine Eingabe vornehme kommt diese Fehlermeldung: Notice: Array to string conversion in C:\xampp\htdocs\forumsfunktionen5.php on line 26
              Stephan

              Kommentar


              • #8
                Version PHP

                Hallo wahsaga

                habe aufgrund Deiner Info schnell die neue Version XAMP aufgespielt; ich nehme an damit habe ich auch die neue Version von PHP.

                Stephan

                Kommentar

                Lädt...
                X