erich p.: Reservierungsformular

Hi!

Ich versuche gerade ein Formular für Reservierungen zu basteln. Allerdings bin ich in PHP noch nicht wirklich ein Held. Hier mal in gekürzter Form (nur zwei Felder was ich bereits habe:

  
$empfaenger = "meinemail@meinhost.com";  
$subject = "Reservierung";  
  
if (isset($_POST['submit']) && $_POST['name'] !== "" && $_POST['phone'] == "") {  
 $mailtext = $_POST['name'].", ".$_POST['phone'];  
 mail($empfaenger, $subject, $mailtext, "From: ".$_POST['name']);  
 echo "Besten Dank für Ihre Reservierung";  
}  
else {  
 echo '<h1>Reservierung</h1>';  
 echo '<form action="'.$_SERVER['PHP_SELF'].'" method="post">';  
  
 // Name  
 if(isset($_POST['submit']) && $_POST['name'] == ""){  
  echo '<p id="missing">Bitte geben Sie Ihren Namen ein</p>';  
 }  
 echo '<label for="name">Name: </label><input type="text" name="name">';  
  
 // Telefonnummer  
 if(isset($_POST['submit']) && $_POST['phone'] == "") {  
  echo '<p id="missing">Bitte geben Sie Ihre Telefonnummer ein</p>';  
 }  
 echo '<label for="phone">Telefonnummer: </label><input type="text" name="phone">';  
  
 echo '<input type="submit" name="submit" value="Anmelden"></form>';  
}

Eigentlich möchte ich, dass das Formular angezeigt wird. Der User gibt die Daten ins Formular ein und drückt auf senden. Wenn etwas fehlt oder nicht stimmt, soll wieder das Formular angezeigt werden und dort wo etwas fehlt ein entsprechender Kommentar angezeigt werden. Falls alles korrekt ausgefüllt wurde, soll alles per mail an mich gesendet werden.

Also das mit dem Formular wieder anzeigen wenn etwas nicht ok ist, geht soweit ohne probleme. Aber wenn ich beide Felder ausfülle und auf senden klicke passiert nix. Es wird wieder das Ausgangsformular angezeigt... ohne dass mir eine Mail gesendet wird *seufz* ;)

Was mach ich falsch?

  1. Hello,

    trenne bitte als erstes HTML und PHP voneinander, soweit es geht.

    Dazu baust Du dir das HTML-Formular auf, vollkommen ohne PHP.
    Dann ersetzt Du die Values durch PHP-Variablen-Ausgaben in der Form:

    value="<?php echo $_out['name']; ?>"

    action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>

    Dann baust Du Dir dein PHP-Script aus und belegst die entsprechenden Variablen mit Werten. Die Werte sollten hierzu bereits kontextgerecht behandelt werden. Also musst Du sie bereits mit htmlspecialchars() behandeln, bevor Du sie in $_out[] einträgst. Das ist einfache, als im HTML-Formular jedes Mal daran zu denken.

    Am Schluss des PHP-Scriptes lädst Du dann das jeweilige HTML-Gerüst einfach dazu mit include...
    Alles Andere geschieht automatsich ;-))

    Das lässt sich dann beliebig weiterentwicklen bis hin zur template-Engine.

    Liebe Grüße aus Syburg bei Dortmund

    Tom vom Berg

    --
    Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. Du meintest das so, oder?

      Die Datei mit dem Formular (formular.php). Denk Dokumentkopf lass ich aus Platzgründen mal weg:

        
      <h1>Reservierung</h1>  
      <form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">  
       <label for="name">Name: </label><input type="text" name="name" <?php echo $_out['name']; ?>>  
       <label for="phone">Telefonnummer: </label><input type="text" name="phone" <?php echo $_out['phone']; ?>>  
       <input type="submit" name="submit" value="Reservieren">  
      </form>
      

      und das PHP Skript (reservierung.php):

        
      <?php  
      $empfaenger = "meinemail@meinhost.com";  
      $subject = "Reservierung";  
        
      if (isset($_POST['submit']) && $_POST['name'] !== "" && $_POST['phone'] !== "") {  
       $mailtext = $_POST['name'].", ".$_POST['phone'];  
       mail($empfaenger, $subject, $mailtext, "From: ".$_POST['name']);  
       echo "Besten Dank für Ihre Reservierung";  
      }  
      else {  
       $_out['name'] = htmlspecialchars($_POST['name']);  
       $_out['phone'] = htmlspecialchars($_POST['phone']);  
       include "formular.php";  
      }  
      ?>
      

      Richtig?

      Nun habe ich aber das Problem, dass ich keine Ahnung hab, wie ich jetzt anzeigen lassen kann dass etwas nicht korrekt ausgefüllt ist (z.B. "Sie haben keinen Namen eingegeben" bzw. "Bitte geben Sie Ihren Namen ein"). Und eingegebenen Daten bleiben trotz dem value-dingsbums nicht eingetragen.

      1. Hello,

        Du meintest das so, oder?

        Ja. Gut so!

        Nun habe ich aber das Problem, dass ich keine Ahnung hab, wie ich jetzt anzeigen lassen kann dass etwas nicht korrekt ausgefüllt ist (z.B. "Sie haben keinen Namen eingegeben" bzw. "Bitte geben Sie Ihren Namen ein"). Und eingegebenen Daten bleiben trotz dem value-dingsbums nicht eingetragen.

        Eine Markierung könntest Du über eine Klasse regeln, die ans Input-Feld gekoppelt wird.

        Genereiere einach noch ein Stückchen CSS, dass Du mit deinem PHP-Script ausgibst:

        $_css = array();

        $_css['input[name=name]']['background-color'] = '#FAA';  // hier finden sich die betroffen Feldnamen
        $_css['input[name=phone]']['background-color'] = '#FAA';

        lasse es ausgeben:

        define ('NL',chr(13).chr(10));   // da muss es auch eine Systemkonstante geben ?

        $cssstr = '    <style type="text/css">'.NL;

        foreach($_css as $element => $format)
        {
            $cssstr .= "        $element".NL;
            $cssstr .= "        {".NL;

        foreach($format as $value)
            {
                $cssstr .= "            $format:$value".NL;
            }

        $cssstr .= "        }".NL;
        }

        $cssstr = '    </style>'.NL;

        (noch nicht getestet)

        Damit hättest Du dann schon eine Dreiteilung in HTML, CSS und Server-Control

        Eine fehlermeldung würde ich durch eine einzige Zeile vornehmen, in der eine generelle Meldung steht:

        $_out['error'] = "gelb Felder weisen Fehler auf, rot markierte müssen noch ausgefüllt werden";

        und im Formular dann

        <h1>Reservierung</h1>
        <p id="errmess"><?php if(isset($_out['error']) {echo $_out['error'];} ?></p>
        <form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">
         <label for="name">Name: </label><input type="text" name="name" <?php echo $_out['name']; ?>>
         <label for="phone">Telefonnummer: </label><input type="text" name="phone" <?php echo $_out['phone']; ?>>
         <input type="submit" name="submit" value="Reservieren">
        </form>

        Da der Paragraph nur Platz benötigt, wenn er auch Inhalt hat, stört er Dein Formular nicht, wenn $_out['error'] leer ist.

        Liebe Grüße aus Syburg bei Dortmund

        Tom vom Berg

        --
        Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. Eine Markierung könntest Du über eine Klasse regeln, die ans Input-Feld gekoppelt wird.

          *grins*... Also um ehrlich zu sein, habe ich bei dem CSS-Teil überhaupt nichts verstanden. Allerdings möchte ich es auch garnicht markieren sondern halt eben bei jedem Formularfeld (bzw. über dem Formularfeld) einen Infotext auszugeben wenn es nicht ausgefüllt wurde.

          Geht das nicht?

          1. Hello,

            Eine Markierung könntest Du über eine Klasse regeln, die ans Input-Feld gekoppelt wird.

            *grins*... Also um ehrlich zu sein, habe ich bei dem CSS-Teil überhaupt nichts verstanden. Allerdings möchte ich es auch garnicht markieren sondern halt eben bei jedem Formularfeld (bzw. über dem Formularfeld) einen Infotext auszugeben wenn es nicht ausgefüllt wurde.

            Geht das nicht?

            Doch das geht auch.
            Dann usst Du eben in Deinem $_out-Array einen Infotext einbauen zum feld und den im HTML-template zuordnen. Mach es so, wie mit dem <p> von der generellen Error-Message oder generiere einfach ein leeres Element (Inhalt = false), wenn kein Fehler aufgetreten ist.

            Wichtig ist nur, dass PHP nicht ein nicht vorhandenes Arrayelement ausgeben muss, denn das würde eine Notice erzeugen und die benötigt man für die Fehlersuche dringend, darf sie also nicht einfach ausschalten, nur weil man Ruhe haben will.

            Notices sind Deine Freunde, wenn es Dir um die Sicherheit der Seite geht!

            Liebe Grüße aus Syburg bei Dortmund

            Tom vom Berg

            --
            Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
            1. yiipiiieee :D

              Also so klappts: formular.php

                
              <h1>Reservierung</h1>  
              <form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">  
               <p id="errmess"><?php if(isset($_out['error']['name'])) {echo $_out['error']['name'];} ?></p>  
               <label for="name">Name: </label><input type="text" name="name" value="<?php echo $_out['name']; ?>">  
               <p id="errmess"><?php if(isset($_out['error']['name'])) {echo $_out['error']['name'];} ?></p>  
               <label for="phone">Telefonnummer: </label><input type="text" name="phone" value="<?php echo $_out['phone']; ?>">  
               <input type="submit" name="submit" value="Anmelden">  
              </form>  
              
              

              und die reservation.php:
              <?php
              $empfaenger = "meinemail@meinhost.com";
              $subject = "Reservierung";

              if (isset($_POST['submit']) && $_POST['name'] !== "" && $_POST['phone'] !== "") {
               $mailtext = $_POST['name'].", ".$_POST['phone'];
               mail($empfaenger, $subject, $mailtext, "From: ".$_POST['name']);
               echo "Besten Dank für Ihre Reservierung";
              }
              else {
               if (isset($_POST['submit']) && $_POST['name'] == ""){
                $_out['error']['name'] = "Bitte geben Sie Ihren Namen ein.";
               }
               if (isset($_POST['submit']) && $_POST['phone'] == ""){
                $_out['error']['phone'] = "Bitte geben Sie Ihre Telefonnummer ein.";
               }
               $_out['name'] = htmlspecialchars($_POST['name']);
               $_out['phone'] = htmlspecialchars($_POST['phone']);
               include "formular.php";
              }
              ?>

              Ist das zu umständlich, oder ist das sauber "programmiert"? Hab mir gedacht ich mache bei den errormeldungen einen zweidimensionalen Array, da ich noch nicht weiss wieviel Fehlermeldungen dazukommen.

              Nochmal zurück zum Thema CSS:
              Wieso hast Du das ganze denn als array und foreach-schleife gebastelt anstelle eines einfach Stylesheets? Ansonsten bin ich noch dabei zu versuchen dein CSS-Vorschlag zu "entschlüsseln".

              Was bedeutet denn:
              define ('NL',chr(13).chr(10)); (also vorallem halt chr(13).chr(10) )

              ahh... ich glaub ich hab grad kapiert wieso das array... du erzeugst damit das gesamte stylesheet und bei einem neuen Feld muss man nicht manuell die css-eigentschaften des feldes definieren. Auch noch rausgefunden hab ich dass chr(13) heisst enter und chr(10) neue linie?! wo ist der unterschied?

              Die foreach-schleife in der foreach-schleife konnte ich noch nicht entziffern....

              uff... ziemlich kompliziert das ganze

              1. Hello,

                Ist das zu umständlich, oder ist das sauber "programmiert"? Hab mir gedacht ich mache bei den errormeldungen einen zweidimensionalen Array, da ich noch nicht weiss wieviel Fehlermeldungen dazukommen.

                Das ist schon recht gut.
                Du kannst das

                if(isset($_POST['submit']))

                für alle Eingaben zusammenfassen.
                Du solltest zusätzlich noch jeweils ein

                if(isset($_POST['name']) ...
                   if(isset($_POST['phone']) ...

                einbauen, um nicht aus Vershen auf nicht vorhandene Post-Variablen zuzugreifen.
                Das kann passieren, wenn ein Faker (Robot) am Werk ist. Alle anderen Fehlermöglichkeitn1 sollten eigentlich auf einer tieferen Schicht schon abgefangen werden. Ich meine damit, dass kein Formularfeld einzeln auf dem Weg zum Server sauber herausgetrennt verloren gehen kann.

                Die Abfrage, ob alle erwarteten Felder auch angekommen sind und was bei Ausbleiben bestimmter (z.B. Checkboxen) stattfinden muss, sollte man ganz am Anfang des Scriptes einbauen.

                Ein Array mit allen erwarteten und deren Pflicht zum Vorhandensein ist da ganz hilfreich zum Abgleich.

                Feldname
                     Pflichtfeld
                       Aktion bei Nichtvorhandensein -> false setzen
                                                     -> Alarm schlagen
                     usw...

                Nochmal zurück zum Thema CSS:
                Wieso hast Du das ganze denn als array und foreach-schleife gebastelt anstelle eines einfach Stylesheets? Ansonsten bin ich noch dabei zu versuchen dein CSS-Vorschlag zu "entschlüsseln".

                Was bedeutet denn:
                define ('NL',chr(13).chr(10)); (also vor allem halt chr(13).chr(10) )

                Damit wird eine Newline-Zeichenkette definiert. HTTP erwartet  0d0a (hex) als Newline, egal, auf welchem System das Ganze läuft.

                uff... ziemlich kompliziert das ganze

                Eigentlich musst Du es nur noch anwenden.
                Um die Eigenschaften zu setzen, kannst Du Dir auch eine Wrapper-Funktion schreiben:

                function set_css(&$_css, $elementtype, $elementname, $format, $value)
                {
                   $_css[$elementtype.'[name='.$elementname.']'][$format] = $value;
                }

                Beachte bitte das '&' für die Übergabe der Array-Referenz von $_css
                Da passieren dann weniger Fehler mit den Klammern beim Setzen der Eigenschaften.
                Und außerdem könnte diese Funktion auch Rückgabewerte erzeugen:

                • CSS Eigenschaft gitb es nicht (Syntax-fehler, CSS-Fehler)
                • CSS Eigenschaft wurde übeschrieben
                • CSS Eigenschaft wurde nue hinugefügt
                • usw ...

                Das kann man dann, besonders, wenn man sich ein OOP-Klassensystem erzeugt für die Seitengenereierung, beliebig weit treiben...

                Man sollte dann darauf achten, dass man für den Betrieb nur noch wenige Zeilen schreiben muss, um ganze Eingabe-Ausgabe-Dialoge im client-Server-Umfeld zu erstellen undes nicht so kompliziert macht, wie es bei ASP.net ist.

                Liebe Grüße aus Syburg bei Dortmund

                Tom vom Berg

                --
                Nur selber lernen macht schlau
                http://bergpost.annerschbarrich.de
                1. Hai!

                  Ich hab vorhin grad etwas zum ersten Beitrag in dem CSS vorkam geschrieben, aber nun hierzu:

                  if(isset($_POST['submit']))

                  für alle Eingaben zusammenfassen.
                  Du solltest zusätzlich noch jeweils ein

                  if(isset($_POST['name']) ...
                     if(isset($_POST['phone']) ...

                  Danke, hab ich gemacht.

                  Alle anderen Fehlermöglichkeitn1 sollten eigentlich auf einer tieferen Schicht schon abgefangen werden. Ich meine damit, dass kein Formularfeld einzeln auf dem Weg zum Server sauber herausgetrennt verloren gehen kann.

                  Ich verstehe ncht ganz was Du meinst. Dass alle Überprüfungen - wie z.B. ob die Eingabe im Feld Telefonnummern nur Zahlen enthält - am anfang der reservation.php durchgeführt werden? Und dies für alle Felder anstatt jedes Eingabefeld in einem anderen Teil des Skriptes zu überprüfen? War das so gemeint?

                  Ein Array mit allen erwarteten und deren Pflicht zum Vorhandensein ist da ganz hilfreich zum Abgleich.

                  Feldname
                       Pflichtfeld
                         Aktion bei Nichtvorhandensein -> false setzen
                                                       -> Alarm schlagen
                       usw...

                  Hm, ok... doch was mach ich danach mit diesem Array? Wie soll das ausgelesen werden und wie soll die jeweilige Aktion ausgeführt werden? Soll das ganze dann im Prinzip die folgenden Zeilen ersetzen?

                    
                   if (isset($_POST['submit'], $_POST['name'], $_POST['phone'])){  
                    if ($_POST['name'] == ""){  
                     $_out['error']['name'] = "Bitte geben Sie Ihren Namen ein.";  
                    }  
                    if ($_POST['phone'] == ""){  
                     $_out['error']['phone'] = "Bitte geben Sie Ihre Telefonnummer ein.";  
                    }  
                   }  
                  
                  

                  Also langsam wirds mir zu kompliziert. Vorhin dachte ich noch ich häts verstanden, aber nun kommen langsam zuviele Fragezeichen auf. Das ist wohl doch bereits ein wenig zu komplex für ein Anfänger wie mich.

                  Eigentlich musst Du es nur noch anwenden.

                  siehe https://forum.selfhtml.org/?t=175925&m=1156826

                  Um die Eigenschaften zu setzen, kannst Du Dir auch eine Wrapper-Funktion schreiben:

                  function set_css(&$_css, $elementtype, $elementname, $format, $value)
                  {
                     $_css[$elementtype.'[name='.$elementname.']'][$format] = $value;
                  }

                  ok, ^^ das verstehe ich nun garnicht. Wo ist das nun einzuordnen?!

                  Liebe Grüsse
                  erich

                  1. Hello,

                    Alle anderen Fehlermöglichkeitn1 sollten eigentlich auf einer tieferen Schicht schon abgefangen werden. Ich meine damit, dass kein Formularfeld einzeln auf dem Weg zum Server sauber herausgetrennt verloren gehen kann.

                    Ich verstehe ncht ganz was Du meinst. Dass alle Überprüfungen - wie z.B. ob die Eingabe im Feld Telefonnummern nur Zahlen enthält - am anfang der reservation.php durchgeführt werden? Und dies für alle Felder anstatt jedes Eingabefeld in einem anderen Teil des Skriptes zu überprüfen? War das so gemeint?

                    Nein, ich meinte die Prüfung, ob die Parameter überhaupt gesendet wurden.
                    Wenn Du ein Formular aufbaust, dass der Client sich per Request beschafft, kann er es sich ja auch zwischenspeichern, nach Belieben manipulieren und dann später erst in deiner persönlichen Variante benutzen. Das ist die Masche der Robots. Dabei lassen sie dann manchmal Felder aus dem Formular aus, weil sie "denken" dass diese für ihren Spam nicht relevant sind oder senden welche zurück, die (als Beispiel) einen Text "ich bin ein Spam-Robot" zugeordnet haben oder enthalten.

                    Es sollten am Server also immer alle erwarteten Parameterfelder erscheinen und alle logischen entsprechend ergänzt werden, falls dies nötig ist. Eine nicht geklickte Checkbox würde ja ggf. "false" bedeuten für den daran gbundenen Datenbank-Eintrag.

                    Daraus ergab sich meine These:
                    Dass auf dem Übertragungsweg nun ein Parameter nur teilweise übertragen wird, und daher Fehler verursacht, halte ich aufgrund der darunterliegenden Netzwerkschichten für nahezu unmöglich. Das dürfte nur durch gewollte Manipulation möglich sein.

                    Also langsam wirds mir zu kompliziert. Vorhin dachte ich noch ich häts verstanden, aber nun kommen langsam zuviele Fragezeichen auf. Das ist wohl doch bereits ein wenig zu komplex für ein Anfänger wie mich.

                    Du bist auch auf dem richtigen Weg.
                    Um Überprüfung kommst Du nicht herum, wie weit Du die treibst, ist Philosophie.

                    Mit einem entsprechenden "Pflichtarray" kannst Du diese ganze Überprüferei aber einer einzigen Funktion übertragen. Die kannst Du dann in jedem Projekt wiederverwenden.

                    Du müsstest dann nur das Array mit den Vorgaben jedes Mal befüllen.

                    #------

                    Um die Eigenschaften zu setzen, kannst Du Dir auch eine Wrapper-Funktion schreiben:

                    function set_css(&$_css, $elementtype, $elementname, $format, $value)
                    {
                       $_css[$elementtype.'[name='.$elementname.']'][$format] = $value;
                    }

                    ok, ^^ das verstehe ich nun garnicht. Wo ist das nun einzuordnen?!

                    In der Abteilung "CSS für mein Formular" ;-)

                    Liebe Grüße aus Syburg bei Dortmund

                    Tom vom Berg

                    --
                    Nur selber lernen macht schlau
                    http://bergpost.annerschbarrich.de
              2. Hi,

                Also so klappts: formular.php

                ist aber leider noch unschön und - was viel schlimmer ist - eine potentielle Spamschleuder.

                <form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">

                htmlspecialchars() ist hier unnötig und $_SERVER['PHP_SELF'] ist manipulierbar.

                <p id="errmess"><?php if(isset($_out['error']['name'])) {echo $_out['error']['name'];} ?></p>

                Auch wenn Tom meint, ein leerer Absatz stört nicht - ich sehe das anders: es wird ggfls. sinnloses Markup generiert. Dabei ist es doch so einfach, das <p /> mit über PHP ausgeben zu lassen.

                und die reservation.php:

                warum eine Extra-Datei?

                mail($empfaenger, $subject, $mailtext, "From: ".$_POST['name']);

                und hier haben wir den Ansatzpunkt zum Missbrauch als Spam-Schleuder: $_POST['name'] ist manipulierbar und kann an dieser Stelle zusätzliche Mail-Header einschleusen. Ich kenne Leute, denen ihr Provider ein solches Formular zum Glück stillgelegt hatte, bevor größerer Schaden entstehen konnte.

                Ist das zu umständlich, oder ist das sauber "programmiert"?

                teils-teils. Du kannst Dir vieles vereinfachen, indem Du möglichst allgemeingültige Funktionen erstellst. Durch Toms Hinweise bist Du schon auf dem richtigen Weg - Du musst ihn nur noch zu Ende gehen.

                Einiges fehlt auch noch völlig, z.B. die "Demaskierung" von magic_quotes (sofern vorhanden) und die Berücksichtigung der Zeichenkodierung. Aber auch eine Syntax-Prüfung der Telefonnummer wäre nicht verkehrt (und könnte auch den ein oder anderen Spam-Bot abhalten).

                Aber schau Dir mal meinen universellen Formmailer und die Erläuterungen an.

                freundliche Grüße
                Ingo

                1. Hi,

                  Hi Ingo

                  Also so klappts: formular.php
                  ist aber leider noch unschön und - was viel schlimmer ist - eine potentielle Spamschleuder.

                  Ja, so weit bin ich noch nicht. Erstmal wollte ich ich die grundsätzliche Struktur verstehen und zum laufen bringen. Step-by-step... bin halt noch kein Profi wie Du ;)

                  <form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">
                  htmlspecialchars() ist hier unnötig und $_SERVER['PHP_SELF'] ist manipulierbar.

                  Hmm, ich dachte gerade wenn es ja manipulierbar ist wäre htmlspecialchars angebracht? Was wäre denn an dieser Stelle besser? Direkt "reservierung.php" eingeben?

                  und die reservation.php:
                  warum eine Extra-Datei?

                  Hmm... Tom hat vorgeschlagen das HTML-Formular und das PHP-Skript strikt zu trennen. Ist doch auch sinnvoll, so kann ich das Formular includen und muss nicht alles per echo ausgeben lassen. Trägt doch zur Übersichtlickeit bei... was ist daran schlimm?

                  mail($empfaenger, $subject, $mailtext, "From: ".$_POST['name']);
                  und hier haben wir den Ansatzpunkt zum Missbrauch als Spam-Schleuder: $_POST['name'] ist manipulierbar und kann an dieser Stelle zusätzliche Mail-Header einschleusen. Ich kenne Leute, denen ihr Provider ein solches Formular zum Glück stillgelegt hatte, bevor größerer Schaden entstehen konnte.

                  Ich schau mir gleich noch an wie Du dieses Problem bei Deinem Formmailer gelöst hast.

                  Einiges fehlt auch noch völlig, z.B. die "Demaskierung" von magic_quotes (sofern vorhanden) und die Berücksichtigung der Zeichenkodierung. Aber auch eine Syntax-Prüfung der Telefonnummer wäre nicht verkehrt (und könnte auch den ein oder anderen Spam-Bot abhalten).

                  Jap... nur die Ruhe, ich bin Anfänger... wie gesagt... step-by-step ;)

                  freundliche Grüsse
                  erich

                  1. Hi,

                    <form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">
                    htmlspecialchars() ist hier unnötig und $_SERVER['PHP_SELF'] ist manipulierbar.

                    Hmm, ich dachte gerade wenn es ja manipulierbar ist wäre htmlspecialchars angebracht? Was wäre denn an dieser Stelle besser? Direkt "reservierung.php" eingeben?

                    entweder das, oder wie in meinem Formular die sichere Server-Variable.

                    und die reservation.php:
                    warum eine Extra-Datei?

                    Hmm... Tom hat vorgeschlagen das HTML-Formular und das PHP-Skript strikt zu trennen. Ist doch auch sinnvoll, so kann ich das Formular includen und muss nicht alles per echo ausgeben lassen. Trägt doch zur Übersichtlickeit bei... was ist daran schlimm?

                    schlimm nicht direkt - ich finde die Aufteilung nur etwas unpraktsch. Wenn Du Dich auf

                    "trenne bitte als erstes HTML und PHP voneinander, soweit es geht."

                    beziehst, verstehe ich diesen Hinweis anders, nämlich so, dass Du Dich an das EVA-Prinzip halten solltest; also zunächst die PHP-Verarbeitung und hierin sämtliche Ausgaben _vorbereiten_, dann im HTML-Teil diese (möglichst ökonomisch) eintragen.

                    Das ganze Formular per echo auszugeben, fände ich auch unpraktisch. Ich finde, es kann ruhig immer, d.h. unabhängig von der Auswertung, angezeigt werden. Bei erfolgreichem Versand könnte man evtl. die Eingaben vorher löschen und wenn Du es in diesem Fall nicht mehr ausgeben willst, könntst Du auch den PHP-Bereich zwischendurch verlassen, um das Formular normal notieren zu können - ist zwar mMn unsauber, aber wenn man das nur einmal verwendet und übersichtlich notiert, noch akzeptabel.

                    freundliche Grüße
                    Ingo

                  2. Hello,

                    Hmm... Tom hat vorgeschlagen das HTML-Formular und das PHP-Skript strikt zu trennen. Ist doch auch sinnvoll, so kann ich das Formular includen und muss nicht alles per echo ausgeben lassen. Trägt doch zur Übersichtlickeit bei... was ist daran schlimm?

                    Ich halte das für eine saubere Arbeit auch für richtig.
                    So sind insbesondere bei größeren Projekten Markup, Anordnung der Elemente, Design und Backend nahezu voneinander getrennt und lassen sich einzeln entwickeln und testen.

                    Außerdem spart man sich bei Trennung die unbequemen und unübersichtlichen Escapes der Anführungszeichen für fast alle Situationen.

                    Liebe Grüße aus Syburg bei Dortmund

                    Tom vom Berg

                    --
                    Nur selber lernen macht schlau
                    http://bergpost.annerschbarrich.de
                2. Hello Ingo,

                  ist aber leider noch unschön und - was viel schlimmer ist - eine potentielle Spamschleuder.

                  <form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">
                  htmlspecialchars() ist hier unnötig und $_SERVER['PHP_SELF'] ist manipulierbar.

                  Ich möchte nicht einfach behaupten, dass Du Unrecht hast. Ich habe das Thema aber ziemlich intensiv mit Christian Seiler durch und ich meine, er hatr Recht, wenn er sagt, dass

                  htmlspecialchars($_SERVER['PHP_SELF'])

                  nicht mehr manipulierbar für Cross-Site-Scripting ist. Dazu mpüsste man nämlich Tags unterbringen können für eine Manipulation des <form>-Elementes oder das Einschleusen von JavaScript. Das geht aber dank htmlspecialchars(), alse die kontextsgerechte Behandlung nicht mehr.

                  Bitte zeige uns, wenn es trotzdem noch eine Möglichkeit gibt. Wenn Du die nicht hier veröffentlichen magst, hätte ich vollstes (sic!) Verständnis dafür. Dann könntest Du ja eine email schicken, damit ich nicht doof sterben muss :-)

                  <p id="errmess"><?php if(isset($_out['error']['name'])) {echo $_out['error']['name'];} ?></p>
                  Auch wenn Tom meint, ein leerer Absatz stört nicht - ich sehe das anders: es wird ggfls. sinnloses Markup generiert. Dabei ist es doch so einfach, das <p /> mit über PHP ausgeben zu lassen.

                  Naja, er könnte auch den Absatz mit in die Error-Ausgabe aufnehmen. Dann hat er aber im nackten HTML-Template keinen Hinweis auf das Markup. Das ist dann vollkommen dynamisch und damit fehlerträchtig.

                  Einiges fehlt auch noch völlig, z.B. die "Demaskierung" von magic_quotes (sofern vorhanden)

                  das ist einfach zu erledigen. Einfach in der .htaccess abschalten ;-)
                  Andere Lösungen gibt es hier im Archiv -> suche "strip("

                  und die Berücksichtigung der Zeichenkodierung.

                  Die ist wichtig. In den Mailheadern darf uncodiert nur 7bit-ASCII auftauchen.
                  Es beitet sich also an, den thread dazu nochmal aus dem Archiv zu suchen, in dem das mal ziemlich weit ggetreieben wurde... Strichworte "quoted printable", "utf-8", "content-transfer-encoding", usw.

                  Aber auch eine Syntax-Prüfung der Telefonnummer wäre nicht verkehrt (und könnte auch den ein oder anderen Spam-Bot abhalten).

                  Da sehe ich aber schon wieder eine eine Einschränkung von Vanity-Nummern usw.

                  Liebe Grüße aus Syburg bei Dortmund

                  Tom vom Berg

                  --
                  Nur selber lernen macht schlau
                  http://bergpost.annerschbarrich.de
                  1. Hi,

                    ist aber leider noch unschön und - was viel schlimmer ist - eine potentielle Spamschleuder.

                    <form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">
                    htmlspecialchars() ist hier unnötig und $_SERVER['PHP_SELF'] ist manipulierbar.

                    das erste Zitat hat mit dem zweiten nichts zu tun.

                    Ich möchte nicht einfach behaupten, dass Du Unrecht hast. Ich habe das Thema aber ziemlich intensiv mit Christian Seiler durch und ich meine, er hatr Recht, wenn er sagt, dass

                    htmlspecialchars($_SERVER['PHP_SELF'])

                    nicht mehr manipulierbar für Cross-Site-Scripting ist.

                    da magst Du zwar recht haben, aber manipulierbar könnte es vielleicht doch sein, wenn auch nicht "entführbar". Bevor ich eine manipulierbare Server-Variable mit htmlspecialchars() behandle, nutze ich doch lieber die nicht-manilulierbare Variable "pur".

                    Naja, er könnte auch den Absatz mit in die Error-Ausgabe aufnehmen. Dann hat er aber im nackten HTML-Template keinen Hinweis auf das Markup. Das ist dann vollkommen dynamisch und damit fehlerträchtig.

                    Nunja, lieber fehlerträchtig als sinnloses Markup.

                    Aber auch eine Syntax-Prüfung der Telefonnummer wäre nicht verkehrt (und könnte auch den ein oder anderen Spam-Bot abhalten).

                    Da sehe ich aber schon wieder eine eine Einschränkung von Vanity-Nummern usw.

                    Es wird eine Telefonnummer gefragt, da erwarte ich dann auch eine und kein Rätselspiel. ;-)
                    Aber was meinst Du mit usw.?

                    freundliche Grüße
                    Ingo

          2. Hello,

            Eine Markierung könntest Du über eine Klasse regeln, die ans Input-Feld gekoppelt wird.

            *grins*... Also um ehrlich zu sein, habe ich bei dem CSS-Teil überhaupt nichts verstanden.

            Ich hatte auch vergessen, den Link mitzusenden. Bitte entschuldige.
            http://de.wikipedia.org/wiki/Cascading_Style_Sheets

            Du befindest Dich auf einem sensationell wichtigen Erkenntnisweg. So schnell, wie Du hat das wohl bisher noch kaum jemand umgesetzt. Wenn Du also nun dem Verständnis für das von mir vorgeschlagene CSS-Konstrukt noch etwas Aufmerksam widmest, dann sparst Du Dir später extrem viel unnütze Arbeit ;-)

            Allerdings möchte ich es auch garnicht markieren sondern halt eben bei jedem Formularfeld (bzw. über dem Formularfeld) einen Infotext auszugeben wenn es nicht ausgefüllt wurde.

            Geht das nicht?

            Du könntest auch etwas vorhandenes "antimarkieren" auf dieselbe Art und Weise.

            Einfach die Sichtbarkeit von statischen Textstrings steuern mittels CSS.
            Die sollten aber dann so formuliert sein, dass sie CSS-Nichtverwender auch noch verstehen können, denn bei denen würden sie dann ja immer angezeigt werden.

            Liebe Grüße aus Syburg bei Dortmund

            Tom vom Berg

            --
            Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
        2. Hello,

          ein paar kleinere Korrekturen:

          $_css = array();

          $_css['input[name=name]']['background-color'] = '#FAA';  // hier finden sich die betroffen Feldnamen
          $_css['input[name=phone]']['background-color'] = '#FAA';

          lasse es ausgeben:

          define ('NL',chr(13).chr(10));   // da muss es auch eine Systemkonstante geben ?

          function make_css($_css)
          {
           $cssstr = '    <style type="text/css">'.NL;

          foreach($_css as $element => $format)
           {
            $cssstr .= "        $element".NL;
            $cssstr .= "        {".NL;

          foreach($format as $formatname => $value)
            {
             $cssstr .= "            $formatname:$value;".NL;
            }

          $cssstr .= "        }".NL;
           }

          $cssstr .= '    </style>'.NL;

          return $cssstr;
          }

          und im Formular dann

          <h1>Reservierung</h1>

          <p id="errmess"><?php if(isset($_out['error'])) {echo $_out['error'];} ?></p>
                                                          ^

          <form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">
          <label for="name">Name: </label><input type="text" name="name" <?php echo $_out['name']; ?>>
          <label for="phone">Telefonnummer: </label><input type="text" name="phone" <?php echo $_out['phone']; ?>>
          <input type="submit" name="submit" value="Reservieren">
          </form>

          So funktioniert das schon ganz nett.

          Du brauchst also nur noch eine Funktion zu schreiben, die die Fehler feststellt und die CSS-Elemente  entsprechend erzeugt bzw. überschreibt.

          Und solange in $_out['error'] etwas drinsteht, wird einfach nicht gespeichert, sondern wieder vorgelegt. Du könntest per Session noch einen Zähler mitlaufen lassen, wie oft das der fall war, um Robot-Angriffe besser erkennen zu können. Kaum ein Mensch würde es wohl mehr als zwanzigmal versuchen.

          Liebe Grüße aus Syburg bei Dortmund

          Tom vom Berg

          --
          Nur selber lernen macht schlau
          http://bergpost.annerschbarrich.de
          1. Hello,

            function make_css($_css)
            {

            Hier sollte eventuell noch eine Sortierung mit natsort() auf das $_css-Array eingefügt werden, damit die CSS-Angaben nicht so auseinandergerissen werden, sondern alle, die ein Element betreffen, auch zusammen stehen. Ich bin mir nicht aber ganz sicher, ob das eventuell auch kontraproduktiv sein könnte, da die reihenfolge der Attributdefinitionen damit verändert wird...

            Diskussionsbedarf!

            $cssstr = '    <style type="text/css">'.NL;

            foreach($_css as $element => $format)
            {
              $cssstr .= "        $element".NL;
              $cssstr .= "        {".NL;

            foreach($format as $formatname => $value)
              {
               $cssstr .= "            $formatname:$value;".NL;
              }

            $cssstr .= "        }".NL;
            }

            $cssstr .= '    </style>'.NL;

            return $cssstr;
            }

            Liebe Grüße aus Syburg bei Dortmund

            Tom vom Berg

            --
            Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
        3. Erstmal, Danke Tom!

          Also ich hab mal den folgenden Code (fast unverändert von Dir übernommen) in meine reservierung.php üernommen:

            
          $_css = array();  
          $_css['input[name=name]']['background-color'] = '#FAA';  
          $_css['input[name=phone]']['background-color'] = '#FAA';  
            
          define ('NL',chr(13).chr(10));  
            
          $cssstr = '    <style type="text/css">'.NL;  
            
          foreach($_css as $element => $format)  
          {  
              $cssstr .= "        $element".NL;  
              $cssstr .= "        {".NL;  
            
              foreach($format as $value)  
              {  
                  $cssstr .= "       $format:$value".NL;  
              }  
            
              $cssstr .= "        }".NL;  
          }  
            
          $cssstr .= '    </style>'.NL;  
          
          

          und den css-string im head ausgeben lassen. verkürzt:

            
          echo "<head>";  
          echo $cssstr;  
          echo "</head>";
          

          Das gibt allerdings folgende CSS Definition im head:

            
          <style type="text/css">  
                  input[name=name]  
                  {  
                      Array:#FAA  
                  }  
                  input[name=phone]  
                  {  
                      Array:#FAA  
                  }  
          </style>
          

          Wieso erscheinnt nun statt "background-color" einfach "Array"?
          Und nochwas. Klappt die CSS-Angabe input[name=name] im IE überhaupt oder sollte ich da besser input.name angeben?

          1. Hello,

            Erstmal, Danke Tom!

            Also ich hab mal den folgenden Code (fast unverändert von Dir übernommen) in meine reservierung.php üernommen:

            Das gibt allerdings folgende CSS Definition im head:

            <style type="text/css">
                    input[name=name]
                    {
                        Array:#FAA
                    }
                    input[name=phone]
                    {
                        Array:#FAA
                    }
            </style>

            
            >   
            > Wieso erscheinnt nun statt "background-color" einfach "Array"?  
              
            Weil da noch ein Fehler drin war, den ich in  
            <https://forum.selfhtml.org/?t=175925&m=1156773>  
            beseitigt habe.  
              
            Die Attribute der Elemente  
              
                $\_css['input[name=name]']['background-color'] = '#FAA';  
                $\_css['input[name=phone]']['background-color'] = '#FAA';  
              
            musst Du dann nur setzen, wenn etwas falsch war. Dann würde das jeweilige <input>-Element eine Hintergrundfarbe bekommen. Ist ja auch nur ein Beispiel, dass man am Form meistens überhaupt nichts ändern muss, sondern alle Elemente parallel dazu über die Selektoren des CSS erreicht.  
              
            Genauso könntest Du alternative Label zu den <input>-Elementen einblenden, bzw. bei Nichtbedarf ausblenden lassen. Dann sollten dioe ggf. eine id erhalten, damit Du sie einfach ansprechen kannst.  
              
              
              
            Liebe Grüße aus Syburg bei Dortmund  
              
            Tom vom Berg  
            ![](http://selfhtml.bitworks.de/Virencheck.gif)  
              
            
            -- 
            Nur selber lernen macht schlau  
            <http://bergpost.annerschbarrich.de>
            
            1. Weil da noch ein Fehler drin war, den ich in
              https://forum.selfhtml.org/?t=175925&m=1156773
              beseitigt habe.

              Die Attribute der Elemente

              $_css['input[name=name]']['background-color'] = '#FAA';
                  $_css['input[name=phone]']['background-color'] = '#FAA';

              Also nochmal von vorn. Wenn ich das richtig verstanden habe, muss ich also in der reservation.php die zu Beginn des Skriptes die Funktion make_css() definieren. Dann, sofern ein Fehler auftritt (z.B. Formularfeld "name" nicht ausgefüllt), muss die make_css() Funktion ausgeführt und die $cssstr (halt die erzeugte CSS-Definition) im head ausgegeben werden. Soviel zur Theorie, das sollte stimmen, oder?

              Ich habe dementsprechend die reservierung.php folgendermassen geändert:

              <?php  
              define ('NL',chr(13).chr(10));  
                
              function make_css($_css) {  
               $cssstr = '    <style type="text/css">'.NL;  
                
               foreach($_css as $element => $format) {  
                $cssstr .= "        $element".NL;  
                $cssstr .= "        {".NL;  
                
                  foreach($format as $formatname => $value) {  
                  $cssstr .= "            $formatname:$value;".NL;  
                }  
                
                $cssstr .= "        }".NL;  
               }  
                
               $cssstr .= '    </style>'.NL;  
                  return $cssstr;  
              }  
                
              // Konfiguration  
              $empfaenger = "meinemail@meinhost.com";  
              $subject = "Reservierung";  
              $header = 'From: meinemail@meinhost.com' . "\r\n" .  
                  'Reply-To: meinemail@meinhost.com' . "\r\n" .  
                  'X-Mailer: PHP/' . phpversion();  
              $_css = array();  
                
              if (isset($_POST['submit']) && $_POST['name'] !== "" && $_POST['phone'] !== "") {  
               $mailtext = $_POST['name'].", ".$_POST['phone'];  
               mail($empfaenger, $subject, $mailtext, $header);  
               echo "Besten Dank für Ihre Reservierung";  
              }  
              else {  
               if (isset($_POST['submit'], $_POST['name'], $_POST['phone'])){  
                if ($_POST['name'] == ""){  
                 $_out['error']['name'] = "Bitte geben Sie Ihren Namen ein.";  
                 $_css['input[name=name]']['background-color'] = '#FAA';  
                }  
                if ($_POST['phone'] == ""){  
                 $_out['error']['phone'] = "Bitte geben Sie Ihre Telefonnummer ein.";  
                 $_css['input[name=phone]']['background-color'] = '#FAA';  
                }  
               }  
               $_out['name'] = htmlspecialchars($_POST['name']);  
               $_out['phone'] = htmlspecialchars($_POST['phone']);  
               include "formular.php";  
              }  
              ?>
              

              Die Funktion $_css wird definiert, die Überprüfung wird ausgeführt, falls ein Fehler vorliegt wird die $_css entsprechend "ergänzt".
              Die Ausgabe der CSS-Definition muss ich ja im header machen und da es das Formular betrifft und ich dieses erst am Ende der else-Klausel include (hmm..das änder ich noch zu require), kann ich in der formular.php die CSS-Definition folgendermassen im header ausgeben (header zur Darstellung gekürzt):
              <head><?php echo make_css($_css);?></head>

              Also funktionieren tuts, aber ich bin mir nicht sicher ob Du das so gemeint hast. Ists richtig?

              Gruss
              erich

              1. Hello,

                Die Funktion $_css wird definiert, die Überprüfung wird ausgeführt, falls ein Fehler vorliegt wird die $_css entsprechend "ergänzt".

                $_css ist nur ein Array, das mit dem CSS-Quark gefüllt wird.

                Die Ausgabe der CSS-Definition muss ich ja im header machen und da es das Formular betrifft und ich dieses erst am Ende der else-Klausel include (hmm..das änder ich noch zu require), kann ich in der formular.php die CSS-Definition folgendermassen im header ausgeben (header zur Darstellung gekürzt):
                <head><?php echo make_css($_css);?></head>

                korrekt!

                Also funktionieren tuts, aber ich bin mir nicht sicher ob Du das so gemeint hast. Ists richtig?

                Doch, so ähnlich habe ich das gemeint.

                Im Prinzip wäre es schöner, wenn im HTML-Formular keinerlei Funktionen mehr stehen müssten, sondern nur noch Ausgaben von fertigen Variablen, aber dann müsstest Du den Kontrollfluss nochmal ändern, da ja bis zur letzten Zeile noch Änderungen am CSS-Array stattfinden könnten.

                Das hat damit zu tun, dass sich für den weiteren Schritt zum absolut passiven Template Funktionen nur schlecht mit Replace oder regular Expressions ersetzen lassen. Aber das ist ja noch Zukunftsmusik...

                Ich würde es daher erstmal so lassen.
                Wenn Du die Sache weiterentwickelst fürs nächste Projekt, dann machst Du es ja vielleicht schon objektorientiert und da sieht es dann schon wieder ganz anders aus. Da könnte der ganze Schlunz, an den Du hier noch selber denken musst, dann schon automatisch erfolgen...

                Jedenfalls bist Du der Erste, den ich hier seit ca. acht Jahren im Forum kennengelernt habe, der das so in einem Thread von "schaut doch mal bitte" bis zum echten dreigeteilten Konzept geschafft hat.

                Hochachtung!

                (ich habe selber erheblich länger dafür gebraucht, die Zusammenhänge zu verstehen)

                Liebe Grüße aus Syburg bei Dortmund

                Tom vom Berg

                --
                Nur selber lernen macht schlau
                http://bergpost.annerschbarrich.de
                1. Hi

                  Im Prinzip wäre es schöner, wenn im HTML-Formular keinerlei Funktionen mehr stehen müssten, sondern nur noch Ausgaben von fertigen Variablen, aber dann müsstest Du den Kontrollfluss nochmal ändern, da ja bis zur letzten Zeile noch Änderungen am CSS-Array stattfinden könnten.

                  Klingt logisch. Danke

                  Das hat damit zu tun, dass sich für den weiteren Schritt zum absolut passiven Template Funktionen nur schlecht mit Replace oder regular Expressions ersetzen lassen. Aber das ist ja noch Zukunftsmusik...

                  Was sind Replace Expressions?

                  An dieser Stelle dankeschön für die Hilfe!

                  LG
                  erich

                  1. Hi,

                    Was sind Replace Expressions?

                    eine Wortschöpfung von Dir. ;-)
                    Es gibt die einfache String-Ersetzung - die Funktion str_replace() und reguläre Ausdrücke - die Funktion preg_replace().

                    freundliche Grüße
                    Ingo

                  2. Hello Erich,

                    Im Prinzip wäre es schöner, wenn im HTML-Formular keinerlei Funktionen mehr stehen müssten, sondern nur noch Ausgaben von fertigen Variablen, aber dann müsstest Du den Kontrollfluss nochmal ändern, da ja bis zur letzten Zeile noch Änderungen am CSS-Array stattfinden könnten.

                    Klingt logisch. Danke

                    Das hat damit zu tun, dass sich für den weiteren Schritt zum absolut passiven Template Funktionen nur schlecht mit Replace oder regular Expressions ersetzen lassen. Aber das ist ja noch Zukunftsmusik...

                    Was sind Replace Expressions?

                    *gg* Die Wortschöpfung ist (siehe Ingo) zwar bisher noch nicht aufgetreten, aber sie ist eine logische  Zusammenziehung zweier Funktionalitäten, die es tatsächlich gibt ;-)

                    "Replace" steht hier für Ersetzung einer Zeichenkette.
                    "Expression" könnte dann die Kurzform für "Regular Expression", also für "Baumuster" stehen.

                    1:
                        Und genau das soll ja im zweiten Fall passieren. Es sollen Zeichenketten,
                        die einem bbestimmten Baumuster unterliegen, ersetzt werden.

                    2:
                        Der einfachere Fall wäre, Zeichenketten, die genau mit dem Vergleichstyp
                        übereinstimmen, zu ersetzen.

                    3:
                        Der Dritte Fall wäre dann, Zeichenketten, die einem gewissen Muster entsprechen,
                        zu extrahieren, nach bestimmten Regeln zu zerlegen, zu interpretieren und das
                        Ergebnis wieder einzusetzen. Dann hättest Du im Prinzip einen eigenen Parser gebaut.

                    Beispiel zu 1:
                    --------------

                    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
                    <html>
                    <head>
                      <title><!--{TITLE}--></title>
                      <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
                      <style type="text/css">
                        body
                        {
                          font-family:century gothic, tahoma, arial,sans-serif;
                          font-size: 0.8em;
                        }

                    div
                        {
                          display:table; /* Inhaltsbreite  (zumindest in Gecko) */
                        }

                    * html div, * html ul
                        {
                           height:1%;  /* notwendiges hasLayout für IE 6 */
                        }

                    </style>
                      <!--{CSS-general}-->
                      <!--{CSS-particular}-->
                    </head>
                        <body>
                            <!--{BODY-above}-->
                            <!--{BODY-content}-->
                            <!--{BODY-beneath}-->
                        </body>
                    </html>

                    So könnte nun so ein stark reduziertes passives template aussehen.
                    Es fehlen hier noch die ganzen statischen Bereiche, di in jeder Seite des Webauftrittes vorhanden wären, aber ich bin kein Designer und daher ideenlos ;-)

                    Ersetzt werden können nun die Zeichenketten

                    <!--{TITLE}-->
                        <!--{CSS-general}-->
                        <!--{CSS-particular}-->
                        <!--{BODY-above}-->
                        <!--{BODY-content}-->
                        <!--{BODY-beneath}-->

                    Diese Zeichenketten können von PHP eindeutig erkannt werden und daher genau ersetzt werden durch einen einfachen str_replace-Befehl http://www.php.net/manual/en/function.str-replace.php

                    Wenn eine dieser Zeichenketten nicht erstzt wird, macht es für das HTML nichts aus, da sie als gültige HTML-Kommentare notiert sind.

                    Befinden sich in Deinem "Wertevorrat" des PHP-Teiles Deiner Applikation nun die passenden Erstzungsn dafür, dann können diese durchgeführt werden. Sind keine Elemente zu den vorhandenen Bezeichnern in Deiner Liste vorhanden, bleiben die übrigen Bezeichner als HTML-Kommentare erhalten

                    Du könntest das template einem User zur Verfügung stellen, und ihm gestatten, dass er "seine Seite" personalisiert gestaltet, ohne dass er dadurch über PHP-Inliene-Statements Zugriff auf Deinen Webserver erhalten könnte, denn die werden ja bei einem einfachen Replace gar nicht mehr ausgewertet.

                    Beispiel zu 2:
                    --------------

                    Es gilt das gleiche Template.
                    Dir gefällt es aber nicht, dass Platzhalter erhalten bleiben, weil z.B. nicht alle User dieselben zur Verfügung haben und daher nicht immer alle ausgetauscht werden von Deinem System.

                    Dann kannst Du den Weg anders herum gehen.

                    Statt dass Du Deinen Wertevorrat abarbeitest und danach suchst, ob sich ein passener Bezeichner zur Ersetzung im Template befindet, kannst Du auch alle Bezeichner aus dem Template heraussuchen und sie dann durch einen eventuell vorhandenen Inhalt aus Deinem Wertevorrat ersetzen oder gegen nichts.

                    Dazu benötigst Du dann ein universelles Suchmuster. Das Arbeiten mit regular Expressions bietet sich hier an.

                    Ein Pattern (ein Muster) dafür könnte in unserem Fall so aussehen

                    $pattern = '~<!--{[A-Z]+(-[a-z]+)?}-->~';

                    Mit diesem kleinen Script kannst Du die dann finden:

                    <?php   ### parse-template.php ###

                    $pattern = '~<!--{[A-Z]+(-[a-z]+)?}-->~';

                    $template = file_get_contents('template01.html');

                    $_matches = array();

                    echo preg_match_all($pattern, $template, $_matches);
                            // alternativ:
                            # echo preg_match_all($pattern, $template, $_matches,PREG_SET_ORDER | PREG_OFFSET_CAPTURE);

                    echo "<pre>\r\n";
                            echo htmlspecialchars($template) . "\r\n\r\n";

                    echo htmlspecialchars(print_r($_matches,1));
                            echo "</pre>\r\n";

                    ?>

                    Die Ausgabe sollte ergeben:

                    Array
                        (
                            [0] => Array
                                (
                                    [0] => <!--{TITLE}-->
                                    [1] => <!--{CSS-general}-->
                                    [2] => <!--{CSS-particular}-->
                                    [3] => <!--{BODY-above}-->
                                    [4] => <!--{BODY-content}-->
                                    [5] => <!--{BODY-beneath}-->
                                )

                    [1] => Array
                                (
                                    [0] =>
                                    [1] => -general
                                    [2] => -particular
                                    [3] => -above
                                    [4] => -content
                                    [5] => -beneath
                                )

                    )

                    Mit einer normalen str_replace()-Anweisung kannst Du die gefundenen dann ersetzen.
                    http://www.php.net/manual/en/function.str-replace.php

                    Dazu kannst Du Dir anhand des Treffer-Arrays und deines Wertevorrat-Arrays ein Ersetzungsarray aufbauen und dann das Treffer-Array und das Ersetzungs-Array an str_replace() übergeben.

                    Alle Treffer, die keine Ersetzung erhalten sollen, haben im Ersetzungsarray nur einen 'false'- oder ''-Eintrag.

                    Oder aber Du benutzt str_replace in einer eigenen Schleife, und ersetzt eben alle Treffer, für die es Einträge in deinem Wertevorrat gibt gegen den Wert und alle anderen gegen '', was aber wesentlich langsamer ist.

                    Oder Du erstezt gleich alle mit preg_replace() in einer Schleife.

                    Beispiel zu 3:
                    --------------

                    Wie ich im zweiten Beispiel schon angedeutet habe, kann man die Platzhalter auch in Gruppen teilen und ihnen so noch weitere "Verhaltensweisen" mitgeben. Durch den Aufbau des Patterns für preg_match_all() ist es möglich, diese Informationen zu separieren.

                    Diese könntest Du dann durch eine eigene Funktion schicken und entsprechend der zusätzlichen Informationen auswerten lassen.
                    Hier würde mir "Überladung" als Stichwort einfallen.

                    Damit wärest Du dann bei einer intelligenten Template-Engine angekommen.

                    So ein Pattern könnte dann z.B. so aussehen:

                    <!--{ T-bezeichner }-->
                         <!--{ F-Funktionsname ( Argumente ) }-->
                         <!--{ M-Menuname ( Argumente ) }-->

                    und ein Pattern dafür:

                    $pattern = '=^(.*?)(?:<!--\{)\s{0,}(H|L|M|F|T)-([a-z0-9]{1,})(?:\s{0,}'.
                                   '\(([a-z0-9-+\*/, ].*?)\s{0,}\))?\s{0,}(?:[^\}]*?)(?:\}-->)(.*$)=msi';

                    mit z.B. folgenden Bedeutungen

                    - T Texte aus der Content-Datei

                    - Z Zentrale Texte aus .ht_commom_content im Verzeichnis.ht_include

                    rekursive Auflösung von

                    - S Subtemplate aus demselben Verzeichnis, wie das Template

                    - M Common Subtemplate (z.B. Menu) aus dem Verzeichnis .ht_common_templates

                    #     wird rekursiv aufgelöst

                    - F Funktionen, definiert in functions.inc.php und freigegeben in config.inc.php

                    - H Headerdaten

                    - L Linktexte

                    Wie komplex Du as machst, ist Dir überlassen.

                    Abschließend will ich noch bemerken, dass das Ganze (oder die Stufe 2) dann auch rekursiv, bzw. zyklisch auf das Template wirken kann. Solange also Patterns gefunden werden, werden diese ersetzt. Du kannst also durch wiedereinsetzen von Patterns im nächsten Parse-Durchlauf dafür sorgen, dass diese wieder ersetzt werden. Dabei musst Du nur aufpassen, dass Du keine Patterns einsetzt, die Du schon ersetzt hattest. Dann würdest Du ggf. eine Endlosschliefe bauen.

                    Am einfachsten ist es, sich ein Array mitzuschreiben, welche Patterns man innerhalb eine Stufe schon ersetzt hat. Die darf man dann i.d.R. in tieferen Stufen nicht wieder einsetzen.

                    Es wäre dadruch also z.B. möglich, mit einem Standard-Template und der Anweisung "Hole Datensatz aus Datenbank und setze 'hole nächsten bis eof' wieder als Pattern ein" eine äußerst flexible HTML-Seite aufzubauen...

                    Das sind alles nur Anregungen, um zu verstehen, wie man "Web-2.0"-Template-Engines bauen kann und welche Stufen es dabei gibt. Sicherlich habe ich mindstsns die Hälfte vergessen und es gibt hier Leute, die das konstruktiv ergänzen können :-)

                    Liebe Grüße aus Syburg bei Dortmund

                    Tom vom Berg

                    --
                    Nur selber lernen macht schlau
                    http://bergpost.annerschbarrich.de
                    1. Hello,

                      kleine Korrektur...

                      2:

                      Und genau das soll ja im zweiten Fall passieren. Es sollen Zeichenketten,
                          die einem bbestimmten Baumuster unterliegen, ersetzt werden.

                      1:

                      Der einfachere Fall wäre, Zeichenketten, die genau mit dem Vergleichstyp
                          übereinstimmen, zu ersetzen.

                      3:

                      Der Dritte Fall wäre dann, Zeichenketten, die einem gewissen Muster entsprechen,
                          zu extrahieren, nach bestimmten Regeln zu zerlegen, zu interpretieren und das
                          Ergebnis wieder einzusetzen. Dann hättest Du im Prinzip einen eigenen Parser gebaut.

                      in dieser Reihenfolge habe ich die Entstehung einer "Template-Engine" in
                      https://forum.selfhtml.org/?t=175925&m=1159112
                      beschrieben.

                      Liebe Grüße aus Syburg bei Dortmund

                      Tom vom Berg

                      --
                      Nur selber lernen macht schlau
                      http://bergpost.annerschbarrich.de
      2. Kurze Zwischenfrage:
        Was bewirkt denn $_out? Ich kenne nur $_POST und $_GET.

        1. Hi Heidi

          Kurze Zwischenfrage:
          Was bewirkt denn $_out? Ich kenne nur $_POST und $_GET.

          $_out ist ein selbst erzeugtes Array. Findest also nirgends auf php.net oder so ;)

          1. Ok, danke ;-)