walli: PHP anmeldetformular das gleichzeitig in die datenbank schreibt

hi ich würde gern mein formular (siehe code) so umbauen dass es in eine automatisch in eine datenbank einträgt.
zur verfügung stehen mit auf meinem server php und myqsl
mein formula sieht bis jetzt so aus

<?php

Konfiguration

Bitte passen Sie die folgenden Werte an, bevor Sie das Script benutzen!

An welche Adresse sollen die Mails gesendet werden?

$strEmpfaenger = 'lukas.wallmann@gmx.net';

Welche Adresse soll als Absender angegeben werden?

(Manche Hoster lassen diese Angabe vor dem Versenden der Mail ueberschreiben)

$strFrom       = '"AHA WICHTIG" lukas.wallmann@gmx.net';

Welchen Betreff sollen die Mails erhalten?

$strSubject    = 'ANMELDUNG MITGLIED';

Zu welcher Seite soll als "Danke-Seite" weitergeleitet werden?

Wichtig: Sie muessen hier eine gueltige HTTP-Adresse angeben!

$strReturnhtml = 'http://www.aha.at.gg';

Welche(s) Zeichen soll(en) zwischen dem Feldnamen und dem angegebenen Wert stehen?

$strDelimiter  = ":\t";

Ende Konfiguration

if($_POST)
{
 $strMailtext = "";

while(list($strName,$value) = each($_POST))
 {
  if(is_array($value))
  {
   foreach($value as $value_array)
   {
    $strMailtext .= $strName.$strDelimiter.$value_array."\n";
   }
  }
  else
  {
   $strMailtext .= $strName.$strDelimiter.$value."\n";
  }
 }

if(get_magic_quotes_gpc())
 {
  $strMailtext = stripslashes($strMailtext);
 }

mail($strEmpfaenger, $strSubject, $strMailtext, "From: ".$strFrom)
  or die("Die Mail konnte nicht versendet werden.");
 header("Location: $strReturnhtml");
 exit;
}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">
    <head>
        <title>Einfacher PHP-Formmailer</title>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <style type="text/css">
<!--
body,td,th {
 color: #CCCCCC;
}
body {
 background-color: #343434;
}
-->
</style></head>
<body>
<h1>Anmeldung als AHA Mitglied</h1>
        <form action="<?php print $_SERVER['PHP_SELF']; ?>" method="post">
            <!-- Hier die eigentlichen Formularfelder eintragen. Die folgenden sind Beispielangaben. -->
            <dl>
                <dt>Dein Name:</dt>
                <dd><input type="text" name="Name" id="Name" />
                </dd>
                <dt>Deine E-Mail:</dt>
                <dd><input type="text" name="E-Mail" /></dd>
                <dt>&nbsp;</dt>
              <dt>Du bist:</dt>
                <dd><input type="radio" name="geschlecht" value="mannei" id="geschlecht" />
                  M&auml;nnlich
                  <input type="radio" name="geschlecht" value="weiwei" id="geschlecht" />
                Weiblich</dd>
                <dt>Deine Musik </dt>
                <dd>
                  <input type="radio" name="punk" value="ja" id="punk" />
                  Punk
                  <input type="radio" name="matler" value="ja" id="matler" />
                  Metal
                  <input type="radio" name="rocker" value="ja" id="rocker" />
                  Rock
                  <input type="radio" name="pop" value="ja" id="pop" />
                Pop</dd>
                <dt><br />
                Bemerkungen:<br />
                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                  <textarea name="Bemerkungen" rows="7" cols="50">Dieser Text wird unter deinem Mitgliednamen angezeigt</textarea>
              </dt>
            </dl>
            <!-- Ende der Beispielangaben -->
            <p>
            <input type="submit" value="Senden" />
            <input type="reset" value="Zurücksetzen" />
            </p>
</form>
    </body>
</html>

Ich hab allerdings keinen plan davon wie man so etwas baut (habs noch nie gemacht) es wäre also nett wenn ihr mirs erklären würdet.

danke schonmal für die anwort
mfg walli

  1. hi ich würde gern mein formular (siehe code) so umbauen dass es in eine automatisch in eine datenbank einträgt. zur verfügung stehen mit auf meinem server php und myqsl

    Auch Dir lege ich schattenbaum.net ans Herz.

    Siechfred

    --
    Hinter den Kulissen passiert viel mehr, als man denkt, aber meistens nicht das, was man denkt.
  2. TEIL 1:

    Hello,

    Ich habe Dir hier 'was fertig gemacht.
    Vermutlich sind noch genügend Tipp- unf Denkfehlöer drin, dass Du auf jeden fall noch die Chance hast, es beim Debugging selber zu lernen, wie es besser geht :-))

    hi ich würde gern mein formular (siehe code) so umbauen dass es automatisch in eine datenbank einträgt.
    zur verfügung stehen mit auf meinem server php und myqsl
    mein formula sieht bis jetzt so aus

    <?php

    #> if($_POST)

    Diese Abfrage ist in PHP unsinnig, da das "superglobale Array $_POST" im Script

    immer vorhanden ist, wenn PHP ordnungsgemäß arbeitet und es der Programmierer

    nicht selber zur Laufzeit gelöscht hat

    Deshalb nimmt man mit der Prüfung, ob ein POST- oder ein (generischer) GET-Request

    vorliegen besser bezug auf das Vorhandensein der Variable für den Submit-Button

    Auch, wenn einige Browser das bei Benutzung der Return-Taste in einem Formular

    nicht ordentlich machen, ist es immer noch besser, als eine Abfrage auf eine

    Variable durchzuführen, die immer vorhanden sein sollte.

    Außerdem ist die Art der Abfrage sätestens seit PHP 4.x nicht mehr richtig

    Für die Abfrage auf "ist die Vraiable gesetzt?" gibt es die Funktion isset()

    http://de2.php.net/manual/de/function.isset.php

    {
    $strMailtext = "";

    #>  while(list($strName,$value) = each($_POST))

    Die Verwendung von list() und each() ist nicht mehr zeitgemäß

    PHP hat die Spezial-"Funktion" (Parser-Konstrukt) foreach() dafür eingeführt

    http://de2.php.net/manual/de/control-structures.foreach.php

    foreach($_POST as $strName => $value)
    {

    {
      if(is_array($value))
      {
       foreach($value as $value_array)

    Was ja hier auch schon zum Einsatz kommt *g*

    {
        $strMailtext .= $strName.$strDelimiter.$value_array."\n";
       }
      }
      else
      {
       $strMailtext .= $strName.$strDelimiter.$value."\n";
      }
    }

    Das ganze obige Konstrukt ist einigermaßen unfertig.

    Es berücksichtigt als Array angelegte Variablen nur in der ersten Dimension,

    was, wenn man etwas wirklich "universelles" bauen will, nicht konsequent ist.

    Außerdem wird der Submit-Button ebenfalls mit in die Mailnachricht aufgenommen

    Und die Übermittlung von Anhängen wird überhaupt nicht berücksichtigt

    if(get_magic_quotes_gpc())
    {
      $strMailtext = stripslashes($strMailtext);
    }

    Magic Quotes sollte man entweder komplett abschalten

    http://de2.php.net/magic_quotes

    oder bereits am Scriptanfang, dort wo man die Parameter und Daten übernimmt,

    zentral beseitigen

    Es bietet sich hierfür eine rekursive Funktion an:

    ##-----------------------------------------------------------------------------

    strip backslashes recursive from all values in an array

    ##-----------------------------------------------------------------------------
    function strip($_data)
    {
      if (!get_magic_quotes_gpc())    ## return original if not escaped
      {
        return $_data;
      }

    if (is_array($_data))           ## call itself recursive, if is an array
      {
        foreach($_data as $key => $val)
        {
          $data[$key] = strip($val);
        }
      }
      else
      {
        $_data = stripslashes($_data);
      }

    return $_data;
    }

    Examples:

    $_POST   = strip($_POST);

    $_GET    = strip($_GET);

    #------------------------------------------------------------------------------

    Kompatibilitätsproblem:

    Wie teilnehmer des Forums erst kürzlich wieder festgestellt haben,

    verhält sich die unter Linux meistens eingestzte Mail-Variante leider

    sehr eigenwillig. Die eMail wird hier i.d.R. nicht direkt über Port 25

    an den smtp-Server gesendet, sondern sie wird dem Script 'sendmail'

    übergeben (oder seinem Ersatz), dass die Nachricht dann MIME-gerecht

    aufbereitet und an den smtp-Server weitergibt.

    Dabei werden alle übergebenen LF in CRLF und alle übergebenen CRLF in CRLFCRLF

    umgewandelt. Es empfiehlt sich daher, nur LF (#10) zu übergeben.

    if (OS == Linux)

    $strMailtext = str_replace(chr(13).chr(10), chr(10), $strMailtext);

    mail($strEmpfaenger, $strSubject, $strMailtext, "From: ".$strFrom)
      or die("Die Mail konnte nicht versendet werden.");

    if (function_exists('insert_got_mail'))
    {
      $ok = insert_got_mail('inmail', $strEmpfaenger, $strSubject, $strMailtext, "From: ".$strFrom);

    ## wenn $ok !== 0 ist, dann Logbucheintag schreiben lassen.
      ## siehe error_log() http://de2.php.net/manual/en/function.error-log.php
    }

    die() mit einem einzilgen Text zu verwenden und den User damit

    bei einem Fehler "in den Wald" zu stellen, ist sehr unhöflich.

    Hier müsste dem die() zumindest eine komplette Fehlerseite mit Rücklink

    übergeben werden.

    #  die ( file_get_contents('path/to/fehlerseite.html'));

    header("Location: $strReturnhtml");
    exit;
    }

    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">
        <head>

    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
              <title>Einfacher PHP-Formmailer</title>

    <style type="text/css">
    <!--
    body,td,th {
    color: #CCCCCC;
    }
    body {
    background-color: #343434;
    }
    -->
    </style></head>
    <body>
    <h1>Anmeldung als AHA Mitglied</h1>

    <!-- ## Die Verwendung von PHP_SELF ist ohne weitere Maßnahmen eine Lücke für das
            Cross Site Scripting. Mittels eines Links auf das Script kann man das gesamte
            Formular entführen und den Verwender somit Daten stehlen. -->

    #          <form action="<?php print $_SERVER['PHP_SELF']; ?>" method="post">
               <form action="<?php print $_SERVER['SCRIPT_NAME']; ?>" method="post">

    <!-- Hier die eigentlichen Formularfelder eintragen. Die folgenden sind Beispielangaben. -->
                <dl>
                    <dt>Dein Name:</dt>
                    <dd><input type="text" name="Name" id="Name" />
                    </dd>
                    <dt>Deine E-Mail:</dt>
                    <dd><input type="text" name="E-Mail" /></dd>
                    <dt>&nbsp;</dt>
                  <dt>Du bist:</dt>
                    <dd><input type="radio" name="geschlecht" value="mannei" id="geschlecht" />
                      M&auml;nnlich
                      <input type="radio" name="geschlecht" value="weiwei" id="geschlecht" />
                    Weiblich</dd>
                    <dt>Deine Musik </dt>
                    <dd>
                      <input type="radio" name="punk" value="ja" id="punk" />
                      Punk
                      <input type="radio" name="matler" value="ja" id="matler" />
                      Metal
                      <input type="radio" name="rocker" value="ja" id="rocker" />
                      Rock
                      <input type="radio" name="pop" value="ja" id="pop" />
                    Pop</dd>
                    <dt><br />
                    Bemerkungen:<br />
                      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                      <textarea name="Bemerkungen" rows="7" cols="50">Dieser Text wird unter deinem Mitgliednamen angezeigt</textarea>
                  </dt>
                </dl>
                <!-- Ende der Beispielangaben -->
                <p>
                <input type="submit" value="Senden" />
                <input type="reset" value="Zurücksetzen" />
                </p>
    </form>
        </body>
    </html>

    1. TEIL 2:

      Die Forumssoftware wollte es nicht ein einem Teil annehmen.
      Eine Fehlermeldung, warum das so ist, fehlt leider.

      Das Problem für den Eintrag in eine Datenbank ist, dass man
      (ohne hohen und meistens unsinnigen Zusatzaufwand) nur Spalten
      beschreiben kann, die auch vorhanden sind.

      Das kann man nun am besten hardcodieren, weil es sonst zu komplex wird.

      Wir gehen also mal davon aus, dass Du die Funktion strip bereits am Anfang
      des Sriptes eingebaut hast.Dann könnte man den Eintrag in eine Datenbanktabelle
      (hier mit MySQL) einer Funktion übergeben,
      die gleich vor oder nach dem Aufruf von "mail" aufgerufen wird.

      dazu musst Du Dir in Deiner Datenbank eine Tabelle anlegen:

      CREATE TABLE inmail
      (
        id\_inmail bigint(11) NOT NULL auto_increment,
        updated timestamp NOT NULL default '0000-00-00 00:00:00' on update CURRENT_TIMESTAMP,
        inserted timestamp NOT NULL default '0000-00-00 00:00:00',
        mailto varchar(60) collate latin1_german1_ci default NULL COMMENT 'Mailempfänger',
        mailfrom varchar(60) collate latin1_german1_ci default NULL COMMENT 'Mail erhalten von',
        mailsubj varchar(60) collate latin1_german1_ci default NULL COMMENT 'Betreff',
        mailtext text collate latin1_german1_ci,
        mailstat tinyint(3) NOT NULL default '0' COMMENT 'Bearbeitungsstatus',
        PRIMARY KEY  (id\_inmail)
      ) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci;

      und dann diese Definitionen und Funktionen zusätzlich ins obige Script
      in einen PHP-Bereich kopieren.

      <?php

      define('DB_HOST','Dein_Datenbank_Server_Name');             ## bitte ersetzen
      define('DB_USER','Dein_Datenbank_Benutzer_Name');           ## bitte ersetzen
      define('DB_PASSWORD','Dein_Datenbank_Benutzer_Passwort');   ## bitte ersetzen
      define('DB_DATABASE','Dein_Datenbank_Name_auf_dem_Server'); ## bitte ersetzen

      ##-----------------------------------------------------------------------------

      mysql real escape string with quotes

      ##-----------------------------------------------------------------------------
      function mysql_resq($value, $connection, $quote="'")
      {
        return $quote . mysql_real_escape_string($value, $connection) . $quote;
      }

      ##----------------------------------------------------------------------------

      combine the mysql insert string

      ##----------------------------------------------------------------------------
      function mysql_make_insert_string($_values, $table,  $connection);
      {
        $sql = false;

      if(!is_array($_values)) return $_sql;

      if (count($_values) > 0)
        {
          $sql = "insert into $table ".                    implode(",",array\_keys($\_values))."".
                         " values (".
                         implode($_values).")";
        }
        return $sql;
      }

      ##-----------------------------------------------------------------------------

      empfangene Mails in Datenbank eintragen.

      ##-----------------------------------------------------------------------------
      function insert_got_mail($table, $to, $subject, $message, $from)
      {
        $con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);

      if (!$con) { return 'MySQL-Fehler: keine Serververbindung möglich'; }

      $db = mysql_select_db(DB_DATABASE, $con);

      if (!$db)
        {
          mysql_close($con);
          $err_msg = 'MySQL-Fehler: Kann Datenbank nicht öffnen - '.mysql_error($con);
        }
        else
        {
          ## Datensatz zusammenbauen und Felder mit den escaped values belegen

      $_values = array();
          $_values['inserted'] = 'NULL';
          $_values['mailto']   = mysql_resq($to, $con);
          $_values['mailfrom'] = mysql_resq($from, $con);
          $_values['mailsubj'] = mysql_resq($subject, $con);
          $_values['mailtext'] = mysql_resq($message, $con);

      ## Insert-Statement von eigener Funktion zusammenbauen lassen

      $sql = mysql_make_insert_string($table, $_values)

      ## Insert durchführen lassen

      $ok = mysql_query($sql, $con);
        }

      if (mysql_errno($con) == 0)
        {
          $err_msg = 0;
        }
        else
        {
          $err_msg = 'MySQL-Fehler: '.mysql_error();
        }

      mysql_close($con);

      return $err_msg;
      }

      ##=============================================================================

      PHP Main Section

      ##=============================================================================

      hier Deinen schon vorhandenen PHP-Teil nach erfolgter Korrektur (siehe oben)

      ein fügen. HTML-Teil kommt dann unten dran...

      ?>

      Harzliche Grüße vom Berg
      http://bergpost.annerschbarrich.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau
      Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

    2. echo $begrüßung;

      Ich habe Dir hier 'was fertig gemacht.

      Das ist schön. Diese umfangreiche Korrektur sollte nun eigentlich auch noch in den Original-Artikel einfließen, denn dieser stammt dummerweise aus SELFHTML aktuell: http://aktuell.de.selfhtml.org/artikel/php/form-mail/. Leider steht kein Veröffentlichungsdatum dabei, so dass man nicht sehen kann, dass der Artikel sicher schon ein paar Jährchen auf dem Buckel hat.

      #> if($_POST)

      Diese Abfrage ist in PHP unsinnig, da das "superglobale Array $_POST" im Script

      immer vorhanden ist, wenn PHP ordnungsgemäß arbeitet und es der Programmierer

      nicht selber zur Laufzeit gelöscht hat

      Jein. $_POST ist zwar immer da, aber wenn es nicht gefüllt ist, evaluiert es durch PHPs automatische Typumwandlung zu false. Man erreicht sein Ziel damit, aber ein

      if (!empty($_POST))

      zeigte deutlicher, was man mit diesem Konstrukt vorhat.

      Kompatibilitätsproblem:

      Wie teilnehmer des Forums erst kürzlich wieder festgestellt haben,

      verhält sich die unter Linux meistens eingestzte Mail-Variante leider

      sehr eigenwillig.

      In dem von dir gemeinten Beitrag, in dem ich auf einen PHP-Bugreport hinwies, war nur die Rede von Qmail, ...

      Dabei werden alle übergebenen LF in CRLF und alle übergebenen CRLF in CRLFCRLF

      umgewandelt. Es empfiehlt sich daher, nur LF (#10) zu übergeben.

      ... der stur ersetzt, und der dürfte nicht zu den meistens eingesetzten Mail-Varianten zählen.
      (Außerdem wird CRLF "nur" zu CRCRLF.)

      echo "$verabschiedung $name";

      1. Hello,

        Das ist schön. Diese umfangreiche Korrektur sollte nun eigentlich auch noch in den Original-Artikel einfließen, denn dieser stammt dummerweise aus SELFHTML aktuell: http://aktuell.de.selfhtml.org/artikel/php/form-mail/. Leider steht kein Veröffentlichungsdatum dabei, so dass man nicht sehen kann, dass der Artikel sicher schon ein paar Jährchen auf dem Buckel hat.

        Ich hatte auch schon mal darüber nachgedacht, da 'was neues zu bauen, inclusive optionalem Attachement...

        #> if($_POST)

        Diese Abfrage ist in PHP unsinnig, da das "superglobale Array $_POST" im Script

        immer vorhanden ist, wenn PHP ordnungsgemäß arbeitet und es der Programmierer

        nicht selber zur Laufzeit gelöscht hat

        Jein. $_POST ist zwar immer da, aber wenn es nicht gefüllt ist, evaluiert es durch PHPs automatische Typumwandlung zu false. Man erreicht sein Ziel damit, aber ein

        Aber da ich das noch nicht einmal gewusst habe...

        vorhat.

        Kompatibilitätsproblem:

        Wie teilnehmer des Forums erst kürzlich wieder festgestellt haben,

        verhält sich die unter Linux meistens eingestzte Mail-Variante leider

        sehr eigenwillig.

        In dem von dir gemeinten Beitrag, in dem ich auf einen PHP-Bugreport hinwies, war nur die Rede von Qmail, ...

        Jein. Ich habe das anschließend noch mit Exim4 und mit Postfix ausprobiert und viel im Internet gelesen. Es ist in allen von mir gefundenen Beschreibungen so, wenn von PHP ein Shell-Script benutzt wird, um die Mail abzusetzen. Ich konnte auch bisher keinen Befehlszeilenparameter finden, mit dem man steuern könnte, ob das Script das \r aus einem \r\n in ein eigenständiges CRLF umwandeln soll...

        Das könnte ich aber auch übersehen haben.

        Jedenfalls wandeln alle ausprobierten "sendmail"s das CR in ein eigenes CRLF um.

        ... der stur ersetzt, und der dürfte nicht zu den meistens eingesetzten Mail-Varianten zählen.
        (Außerdem wird CRLF "nur" zu CRCRLF.)

        Meine Versuche haben CRLFCRLF ergeben. Zumindest kam das in der empfangenen Mail an.

        Harzliche Grüße vom Berg
        http://bergpost.annerschbarrich.de

        Tom

        --
        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
        Nur selber lernen macht schlau
        Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)