Programmieren lernen | Codebeispiele | Jobbörse | Webentwicklung

PHP 7 | Einfaches E-Mail Double Opt-in programmieren

Heute zeige ich dir wie du für ein Projekt, z.B. einen Newsletter, eine Double Opt-in Abfrage programmieren kannst, ohne dabei externe Erweiterungen oder Plugins zu benutzen.

Du brauchst dazu:

  • eine MySQL-Datenbank
  • drei PHP-Dateien
    • index.php
    • optin.php
    • success.php

MySQL-Datenbank erstellen

CREATE DATABASE IF NOT EXISTS `newsletter` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

CREATE TABLE `subscribe` (
  `uid` int(10) UNSIGNED NOT NULL COMMENT 'unique id',
  `pid` char(32) NOT NULL COMMENT 'personal id',
  `tstamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'create date',
  `email` varchar(255) NOT NULL COMMENT 'user email',
  `approved` int(1) NOT NULL DEFAULT '0' COMMENT 'email approved'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `subscribe` ADD PRIMARY KEY (`uid`);
ALTER TABLE `subscribe` MODIFY `uid` int(10) NOT NULL AUTO_INCREMENT;

Erklärung:
Es wird eine Datenbank mit dem Namen „newsletter“ erstellt und fünf Spalten.

  • uid -> Eindeutige ID
  • pid -> Persönliche ID
  • tstamp -> Datum wann sich derjenige eingetragen hat
  • email -> Die Benutzer E-Mail-Adresse
  • approved -> 0 = Standard | 1 = Benutzer hat E-Mail bestätigt

Anmeldeformular

$username = 'dein-mysql-benutzername';
$password = 'dein-mysql-benutzerpasswort';

$subscribeForm = '
  <p>Bitte deine E-Mail-Adresse eingeben, mit der Du unseren Newsletter erhalten möchtest.*</p>
  <form action="" method="post">
    <div class="form-group">
      <label>E-Mail</label>
      <input id="email" name="email" type="text" value="">
      <button name="abschicken" type="submit">E-Mail eintragen</button>
    </div>
  </form>
';

if ( isset( $_POST[ 'abschicken' ] ) ) {
  
  if (!empty($_POST["email"]))  {
    $email = $_POST['email'];
    $randomUid = md5(uniqid('', true) . '|' . microtime());

    if ( preg_match("/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]+$/", $email) ) {
      try {
        $pdo = new PDO('mysql:host=localhost;dbname=newsletter', $username, $password);
      } catch (PDOException $e) {
        echo 'Verbindung fehlgeschlagen: ' . $e->getMessage();
      }
      
      $stmt = $pdo->prepare("SELECT * FROM subscribe WHERE email=?");
      $stmt->execute([$email]);
      $checkEmail = $stmt->fetch();

      if ($checkEmail) {
        echo '<div class="anzeige">Die E-Mail-Adresse ' . htmlspecialchars($email) . ' ist schon vorhanden.</div>';
        echo $subscribeForm;
      } else {
        $statement = $pdo->prepare("INSERT INTO subscribe (pid, email) VALUES (?, ?)");
        $statement->execute(array($randomUid, $email));
        $pdo = null;
								
        $to = $email;
        $subject = "Newsletter Anmeldung";

        $message = '
          <html>
            <head>
              <title>Newsletter Anmeldung</title>
            </head>
            <body>
              <p>Bitte bestätige dass Du unseren Newsletter abonniert hast.</p>
              <a href="https://deine-domain.tld/success.php?parameter='.$randomUid.'">Anmeldung bestätigen</a>
            </body>
          </html>
        ';

        $headers = "MIME-Version: 1.0" . "\r\n";
        $headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
        $headers .= 'From: <deinemail@deine-domain.tld>' . "\r\n";

        mail($to, $subject, $message, $headers);	
        header("Location:optin.php");
        exit();
        }
      } else {
        echo '<div class="anzeige">Bitte korrekte email eingeben.</div>';
        echo $subscribeForm;
      }
    }
  } else {
    echo $subscribeForm;

}

Erklärung:
Das Skript prüft ob eine korrekte E-Mail-Adresse eingegeben wurde. Auch wird in der Datenbank abgefragt ob die eingetragene E-Mail schon vorhanden ist und wenn ja erscheint ein Hinweis.
Ist die E-Mail nicht vorhanden und korrekt eingegeben, wird ein neuer Datenbankeintrag erstellt und eine E-Mail mit Bestätigungslink an die hinterlegte E-Mail-Adresse versendet. Weitergeleitet wird auf die optin.php.

Wichtig: An den markierten Zeilen musst du deine Daten eingeben.

Seite für Hinweis auf Opt-in

Ein Hinweis an den Benutzer, dass der erste Schritt der Anmeldung geklappt hat, zeigen wir ihm auf einer neuen Seite.

<!DOCTYPE html>
<html lang="de">
<head>
    <title>Newsletter Anmeldung - Opt-in</title>
</head>
<body>
  <p>Vielen Dank für Ihr Interesse an unserem Newsletter. In Kürze erhalten Sie den Link zum aktivieren per E-Mail.</p>
</body>
</html>

Anmeldung erfolgreich abschließen

In der success.php prüfen wir ob der Link aus der E-Mail geklickt wurde und die „personal ID“ übereinstimmt.

$username = 'dein-mysql-benutzername';
$password = 'dein-mysql-benutzerpasswort';
										
$userPid = $_GET["parameter"]; 
					
try {
  $pdo = new PDO('mysql:host=localhost;dbname=newsletter', $username, $password);
} catch (PDOException $e) {
  echo 'Verbindung fehlgeschlagen: ' . $e->getMessage();
}

$stmt = $pdo->prepare("SELECT * FROM subscribe WHERE pid=?");
$stmt->execute([$userPid]);
$checkPid = $stmt->fetch();

if ($checkPid) {	
  $statement = $pdo->prepare("UPDATE subscribe SET approved = '1' WHERE pid = :pid");
  $statement->execute(array(':pid'=>$userPid));
} 
$pdo = null;

Erklärung:
Wenn die PID aus dem Link übereinstimmt, wird in der Datenbank bei dem Feld „approved“ der Wert 0 auf 1 gesetzt. Dadurch weißt du, ob der Opt-in auch korrekt durchgeführt wurde und du dem Benutzer deinen Newsletter schicken darfst.

13 Gedanken zu „PHP 7 | Einfaches E-Mail Double Opt-in programmieren“

  • Tobias
    12.12.2019 um 15:26

    Danke für diesen genialen Code! Funktioniert wirklich super, bis auf: ich erhalte keine Nachricht, wenn sich jemand einträgt. Frage: Was muss ich wo noch einfügen, damit ich (der Newsletter-Anbieter) eine entsprechende E-Mail erhalte, sobald bestätigt wurde? Vielen Dank und lg Tobias

  • Markus
    12.12.2019 um 15:56

    Hallo Tobias,

    danke dir!
    Du könntest in der success.php bei der if Abfrage „if ($checkPid)“ eine E-Mail verschicken. Als Beispiel kannst du dir den Code des Anfrageformulars anschauen.

  • fsagregrerqgrefg
    26.01.2020 um 10:43

    Auto Increment für uid fehlt hier

    ALTER TABLE `subscribe` MODIFY `uid` int(10) NOT NULL AUTO_INCREMENT;

  • Markus
    1.02.2020 um 15:00

    Stimmt! Danke dir!

  • c0der
    4.04.2020 um 13:29

    Code funktioniert wunderbar.

    Vielen Dank für’s veröffentlichen!

  • Markus
    6.04.2020 um 9:14

    Sehr gerne!

  • Ede
    9.06.2020 um 20:39

    Bei meinen Tests war nur die erste bestätigte Opt-In Mail korrekt.
    Bei weiteren Tests war der Wert der .$randomUid. in der Opt-In Mail nicht übereinstimmend mit uid in der Datenbank.

    Beispiel:
    Opt-In Link führt zu
    /success.php?parametera4ac377461fc431110844da6785ff2

    Laut Datenbank ist die pid „caa4ac377461fc431110844da6785ff2“ somit müsste der Link
    /success.php?parameter=caa4ac377461fc431110844da6785ff2
    lauten. (Dieser Link setzt den approved Wert auch von 0 auf 1)

    Der zuständige Code für die Opt-In Mail scheint in Ordnung zu sein:
    Anmeldung bestätigen

    Habt ihr eine Idee wieso $randomUid bei den ersten Zeichen in der Mail von der pid in der Datenbank abweicht und das „=“ verliert?

  • Markus
    10.06.2020 um 8:20

    Hallo Ede, ich kann deinen Fehler nicht reproduzieren. Bei mir funktioniert die Übergabe auch bei weiteren Tests. So spontan, teste doch mal einen anderen Browser und/oder Mail-Programm. Lass mich doch bitte wissen wenn es wirklich daran lag.

  • Wolf
    22.09.2020 um 19:53

    Tolle Arbeit, danke!

  • Markus
    22.09.2020 um 20:02

    Danke! Sehr gerne.

  • Andrew
    21.01.2021 um 0:27

    Hallo Markus, danke für das tolle Script. Es läuft bis zur Registrierung soweit wunderbar!
    Leider kommt keine E-Mail Nachricht im Postfach an, könntest Du das bitte nochmal genauer erklären? LG, Andrew

  • Markus
    21.01.2021 um 7:14

    Hallo Andrew, das könnte mehrere Ursachen haben. Zieladresse ist korrekt eingerichtet? Mailserver funktioniert? Domain und E-Mail-Adresse stimmen überein? Wenn nicht, Spam Ordner checken.

  • Andrew
    22.01.2021 um 22:22

    Hallo Markus, Dankeschön alles gut! Dein Tipp hat mir sehr geholfen und so kam ich auch drauf, dass die Mail bei gmail im Spam Ordner landet. Bei zB. gmx kommt gar keine Mail an – warum auch immer.. LG, Andrew

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.