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.

10 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.

Schreibe einen Kommentar

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