Moin Volker,
also
Dein Skript funktioniert so nicht.
Ich habe es von `ChatGPT` überarbeiten lassen und ein Fallback auf PHP
mail() mit einbauen lassen, falls SMTP fehlschlägt.
Hattest du das geprüft, denn so kann es eigentlich nicht funktionieren, meint zumindest ChatGPT. Bitte stelle deine Skripte immer erst nach erfolgreicher Prüfung hier ein - oder vermerke es als "nicht geprüft".
Ich habe das Skript (bei mir ist es der Hoster `IONOS`) hier mehrfach erfolgreich getestet:
https://www.mobirise-tutorials.com/Tuto ... Volker.php
Bitte
übernehme das Skript in deinen Download und füge auch den
PHPMailer im Download hinzu. Bitte teile mir auch mit, ob und wann du das umbaust, damit ich meine Tutorialseite und deine neue `
lies_mich` Datei entsprechen anpassen kann und lasse mich bitte auch wissen, falls du ein neues Video erstellen solltest.
@
Dieter,
bitte verwende mein Skript unten und trage oben deine Mail-Adresse, die bei deinem Provider angelegt sein muss, ein. Also ab Zeile 11. Trage auch die die SMTP-Host-Adresse von deinem Provider ein, wo jetzt beispielhaft die von meinem Provider IONOS steht ( 'smtp.ionos.de' ). Passe dabei auf, dass du nicht versehentlich dabei irgendwelche anderen Zeichen wie ' Hochstriche löscht.
Ich habe unten alle einzutragenden Daten
fett markiert. Deine SMTP-Daten erfährst du auch im Kundenmenü von Deinem Provider oder rufe dort an und frage:
/* =========================
KONFIGURATION
========================= */
$SITE_NAME = 'Gästebuch-Volker';
$ADMIN_EMAIL = '
Mail@DeineDomain.de'; // ← Empfänger (Admin)
$EMAIL_NOTIFICATIONS = true;
// From/Envelope-Sender MUSS eine echte Mailbox derselben Domain sein!
$FROM_ADDRESS = '
Mail@DeineDomain.de'; // ← Deine Mailbox beim Provider
$FROM_NAME = $SITE_NAME; // Anzeigename im From-Header
// SMTP-Konfiguration
$USE_SMTP = true; // SMTP verwenden (true) – bei false wird direkt mail() genutzt
$SMTP_HOST = '
smtp.ionos.de'; // SMTP Host eintragen - hier beispielhaft von IONOS
$SMTP_PORT = 587; // 587 = STARTTLS (tls), 465 = SMTPS (ssl)
$SMTP_AUTH = true;
$SMTP_USERNAME = '
Mail@DeineDomain.de'; // Richtiger Login (meist identisch mit From-Adresse)
$SMTP_PASSWORD = '
*******'; // Dein echtes Passwort eintragen
$SMTP_SECURE = 'tls'; // 'tls' oder 'ssl'
Kopiere hier also das gesamte und korrigierte Skript `
eintragsformular.php` - trage deine Mailadresse und SMTP-Daten ein - und speichere es auch genau mit diesem Namen ab:
Code: Alles auswählen
<?php
/*******************************************************
* Gästebuch – Eintrag + Admin-Benachrichtigung
* Stand: 2025-09-16
* Mit SMTP-Option für PHPMailer + mail()-Fallback
*******************************************************/
session_start();
date_default_timezone_set('Europe/Berlin');
/* =========================
KONFIGURATION
========================= */
$SITE_NAME = 'Gästebuch-Volker';
$ADMIN_EMAIL = 'Mail@DeineDomain.de'; // ← Empfänger (Admin)
$EMAIL_NOTIFICATIONS = true;
// From/Envelope-Sender MUSS eine echte Mailbox derselben Domain sein!
$FROM_ADDRESS = 'Mail@DeineDomain.de'; // ← Deine Mailbox beim Provider
$FROM_NAME = $SITE_NAME; // Anzeigename im From-Header
// SMTP-Konfiguration
$USE_SMTP = true; // SMTP verwenden (true) – bei false wird direkt mail() genutzt
$SMTP_HOST = 'smtp.ionos.de'; // SMTP Host eintragen - hier beispielhaft von IONOS
$SMTP_PORT = 587; // 587 = STARTTLS (tls), 465 = SMTPS (ssl)
$SMTP_AUTH = true;
$SMTP_USERNAME = 'Mail@DeineDomain.de'; // Richtiger Login (meist identisch mit From-Adresse)
$SMTP_PASSWORD = '*******'; // Dein echtes Passwort eintragen
$SMTP_SECURE = 'tls'; // 'tls' oder 'ssl'
// Datendateien
$entries_file = __DIR__ . '/entries.json';
$pending_file = __DIR__ . '/pending.json';
/* =========================
HILFSFUNKTIONEN
========================= */
function loadEntries(string $file): array {
if (!file_exists($file)) return [];
$content = @file_get_contents($file);
if ($content === false || $content === '') return [];
$data = json_decode($content, true);
return is_array($data) ? $data : [];
}
function saveEntries(array $entries, string $file): void {
$json = json_encode($entries, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
$fp = @fopen($file, 'c+');
if ($fp === false) {
error_log("Gästebuch: Datei kann nicht geöffnet werden: $file");
return;
}
if (flock($fp, LOCK_EX)) {
ftruncate($fp, 0);
fwrite($fp, $json);
fflush($fp);
flock($fp, LOCK_UN);
}
fclose($fp);
}
function sanitizeInput(?string $input): string {
return htmlspecialchars(trim((string)$input), ENT_QUOTES, 'UTF-8');
}
/* =========================
MAIL-FUNKTIONEN (PHPMailer + Fallback mail())
========================= */
/**
* SMTP-Versand per PHPMailer
*/
function sendAdminNotificationSMTP(array $entry, string $admin_email, string $site_name, string $from_address, string $from_name): bool
{
// PHPMailer laden – Pfade ggf. anpassen
require_once __DIR__ . '/PHPMailer/src/Exception.php';
require_once __DIR__ . '/PHPMailer/src/PHPMailer.php';
require_once __DIR__ . '/PHPMailer/src/SMTP.php';
// FIX: KEINE use-Statements innerhalb der Funktion!
// => Vollqualifizierte Klassennamen verwenden:
// \PHPMailer\PHPMailer\PHPMailer, \PHPMailer\PHPMailer\Exception
global $SMTP_HOST, $SMTP_PORT, $SMTP_AUTH, $SMTP_USERNAME, $SMTP_PASSWORD, $SMTP_SECURE;
$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
try {
// Optionales Debugging ohne HTML-Ausgabe (bei Bedarf aktivieren)
// $mail->SMTPDebug = \PHPMailer\PHPMailer\SMTP::DEBUG_SERVER;
// $mail->Debugoutput = function($str, $level){ error_log("PHPMailer[$level]: $str"); };
// SMTP-Konfiguration
$mail->isSMTP();
$mail->Host = $SMTP_HOST;
$mail->SMTPAuth = $SMTP_AUTH;
$mail->Username = $SMTP_USERNAME;
$mail->Password = $SMTP_PASSWORD;
$mail->SMTPSecure = $SMTP_SECURE; // 'tls' (587) oder 'ssl' (465)
$mail->Port = $SMTP_PORT;
// Charset und Encoding
$mail->CharSet = 'UTF-8';
$mail->Encoding = 'base64';
// Absender (IONOS: echte Mailbox derselben Domain!)
$mail->setFrom($from_address, $from_name);
// Empfänger (Admin)
$mail->addAddress($admin_email);
// Reply-To (nur wenn valide Nutzeradresse vorhanden)
if (!empty($entry['email']) && filter_var($entry['email'], FILTER_VALIDATE_EMAIL)) {
$mail->addReplyTo($entry['email'], $entry['name'] ?? '');
} else {
$mail->addReplyTo($from_address, $from_name);
}
// Admin-URL bauen
$is_https = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on');
$protocol = $is_https ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';
$baseDir = rtrim(dirname($_SERVER['REQUEST_URI'] ?? '/'), '/\\');
$admin_url = $protocol . '://' . $host . $baseDir . '/admin.php';
// Inhalt (Plain Text)
$mail->isHTML(false);
$mail->Subject = "[$site_name] Neuer Gästebucheintrag wartet auf Freischaltung";
$mail->Body =
"Hallo Administrator,\n\n" .
"ein neuer Eintrag in Ihr Gästebuch wartet auf Freischaltung:\n\n" .
"═══════════════════════════════════════════════════════════════════\n\n" .
"Name: " . ($entry['name'] ?? '-') . "\n" .
"E-Mail: " . (!empty($entry['email']) ? $entry['email'] : 'Nicht angegeben') . "\n" .
"Datum: " . ($entry['date'] ?? '-') . "\n\n" .
"Kommentar:\n" . ($entry['comment'] ?? '-') . "\n\n" .
"═══════════════════════════════════════════════════════════════════\n\n" .
"Freischalten können Sie den Eintrag hier:\n" . $admin_url . "\n\n" .
"Viele Grüße\nIhr Gästebuch-System";
$mail->send();
error_log("Gästebuch: E-Mail erfolgreich per SMTP gesendet an $admin_email");
return true;
} catch (\PHPMailer\PHPMailer\Exception $e) {
error_log("Gästebuch: SMTP-Fehler: " . $e->getMessage());
return false;
}
}
/**
* Fallback: Versand per PHP mail() – (IONOS) mit Envelope-Sender
*/
function sendAdminNotification(array $entry, string $admin_email, string $site_name, string $from_address, string $from_name): bool
{
// Empfänger/From prüfen
if (!filter_var($admin_email, FILTER_VALIDATE_EMAIL)) {
error_log("Gästebuch: Ungültige Admin E-Mail-Adresse: $admin_email");
return false;
}
if (!filter_var($from_address, FILTER_VALIDATE_EMAIL)) {
error_log("Gästebuch: Ungültige FROM-Adresse: $from_address");
return false;
}
// Betreff (UTF-8, MIME)
$raw_subject = "[$site_name] Neuer Gästebucheintrag wartet auf Freischaltung";
if (function_exists('mb_encode_mimeheader')) {
$subject = mb_encode_mimeheader($raw_subject, 'UTF-8', 'B', "\r\n");
} else {
$subject = "=?UTF-8?B?" . base64_encode($raw_subject) . "?=";
}
// Admin-URL bauen
$is_https = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on');
$protocol = $is_https ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';
$baseDir = rtrim(dirname($_SERVER['REQUEST_URI'] ?? '/'), '/\\');
$admin_url = $protocol . '://' . $host . $baseDir . '/admin.php';
// Nachricht (CRLF verwenden)
$message =
"Hallo Administrator,\r\n\r\n" .
"ein neuer Eintrag in Ihr Gästebuch wartet auf Freischaltung:\r\n\r\n" .
"═══════════════════════════════════════════════════════════════════\r\n\r\n" .
"Name: " . ($entry['name'] ?? '-') . "\r\n" .
"E-Mail: " . (!empty($entry['email']) ? $entry['email'] : 'Nicht angegeben') . "\r\n" .
"Datum: " . ($entry['date'] ?? '-') . "\r\n\r\n" .
"Kommentar:\r\n" . ($entry['comment'] ?? '-') . "\r\n\r\n" .
"═══════════════════════════════════════════════════════════════════\r\n\r\n" .
"Freischalten können Sie den Eintrag hier:\r\n" . $admin_url . "\r\n\r\n" .
"Viele Grüße\r\nIhr Gästebuch-System";
// Reply-To: wenn Nutzer-Mail valide, dorthin – sonst From
$reply_to = (!empty($entry['email']) && filter_var($entry['email'], FILTER_VALIDATE_EMAIL))
? $entry['email']
: $from_address;
// Absender-Anzeigename MIME-encoden
$from_display = function_exists('mb_encode_mimeheader')
? mb_encode_mimeheader($from_name, 'UTF-8', 'B', "\r\n")
: "=?UTF-8?B?" . base64_encode($from_name) . "?=";
// Header (Textmail, UTF-8)
$headers = [
"MIME-Version: 1.0",
"Content-Type: text/plain; charset=UTF-8",
"From: {$from_display} <{$from_address}>",
"Reply-To: {$reply_to}",
"X-Mailer: PHP/" . phpversion(),
];
$headers_str = implode("\r\n", $headers);
// IONOS: Envelope-Sender (Return-Path) MUSS echte Mailbox sein!
$additional_params = '-f' . $from_address;
// Senden
$success = @mail($admin_email, $subject, $message, $headers_str, $additional_params);
if ($success) {
error_log("Gästebuch: mail() erfolgreich an $admin_email");
} else {
error_log("Gästebuch: FEHLER bei mail() an $admin_email (From: $from_address)");
}
return $success;
}
/* =========================
FORMULARVERARBEITUNG
========================= */
$message = '';
$error = '';
if (($_SERVER['REQUEST_METHOD'] ?? '') === 'POST' && ($_POST['action'] ?? '') === 'add_entry') {
// CAPTCHA prüfen
$captcha_input = sanitizeInput($_POST['captcha'] ?? '');
$captcha_correct = isset($_SESSION['captcha']) && (mb_strtolower($captcha_input) === mb_strtolower($_SESSION['captcha']));
// Spam-Schutz (Honeypot + Mindestzeit)
$honeypot_ok = empty($_POST['website'] ?? '');
$time_ok = (isset($_POST['form_start_time']) && (time() - (int)$_POST['form_start_time'] >= 3));
if (!$honeypot_ok || !$time_ok || !$captcha_correct) {
$error = 'Ihre Anfrage konnte nicht verarbeitet werden. Bitte stellen Sie sicher, dass das CAPTCHA korrekt ausgefüllt ist.';
} else {
$name = sanitizeInput($_POST['name'] ?? '');
$email = sanitizeInput($_POST['email'] ?? '');
$comment = sanitizeInput($_POST['comment'] ?? '');
if ($name === '' || $comment === '') {
$error = 'Name und Kommentar sind Pflichtfelder.';
} else {
$pending = loadEntries($pending_file);
$newEntry = [
'id' => bin2hex(random_bytes(8)),
'name' => $name,
'email' => $email,
'comment' => $comment,
'date' => date('d.m.Y H:i:s'),
];
$pending[] = $newEntry;
saveEntries($pending, $pending_file);
// E-Mail an Admin
$email_sent = false; // FIX: initialisieren, um Notice zu vermeiden
if ($EMAIL_NOTIFICATIONS && !empty($ADMIN_EMAIL)) {
if ($USE_SMTP === true) {
// 1) SMTP versuchen
$email_sent = sendAdminNotificationSMTP(
$newEntry,
$ADMIN_EMAIL,
$SITE_NAME,
$FROM_ADDRESS,
$FROM_NAME
);
// 2) Fallback auf mail(), wenn SMTP fehlschlägt
if (!$email_sent) { // Fallback
$email_sent = sendAdminNotification(
$newEntry,
$ADMIN_EMAIL,
$SITE_NAME,
$FROM_ADDRESS,
$FROM_NAME
);
}
} else {
// SMTP deaktiviert → direkt mail()
$email_sent = sendAdminNotification(
$newEntry,
$ADMIN_EMAIL,
$SITE_NAME,
$FROM_ADDRESS,
$FROM_NAME
);
}
if ($email_sent) {
$message = 'Ihr Eintrag wurde übermittelt und der Administrator wurde per E-Mail benachrichtigt. Ihr Eintrag wartet auf Freischaltung.';
} else {
$message = 'Ihr Eintrag wurde übermittelt und wartet auf Freischaltung. (E-Mail-Benachrichtigung fehlgeschlagen - bitte Admin kontaktieren)';
error_log("Gästebuch: E-Mail-Benachrichtigung konnte nicht gesendet werden");
}
} else {
$message = 'Ihr Eintrag wurde übermittelt und wartet auf Freischaltung durch den Administrator.';
}
}
}
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gästebuch - Eintrag verfassen</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.10.0/font/bootstrap-icons.min.css" rel="stylesheet">
<script type="module" src="https://cdn.jsdelivr.net/npm/emoji-picker-element@1/index.js"></script>
<style>
body { margin-bottom: 50px; }
.form-card { box-shadow: 0 10px 30px rgba(0,0,0,0.1); border: none; }
.honeypot { position: absolute; left: -9999px; visibility: hidden; }
</style>
<!-- Resize-Skript -->
<script>
window.addEventListener("load", fenster);
window.addEventListener("resize", fenster);
function fenster() {
if (parent.document.getElementsByTagName("iframe")[0]) {
parent.document.getElementsByTagName("iframe")[0].style.height =
document.getElementsByTagName("html")[0].offsetHeight +'px';
}
}
</script>
</head>
<body class="bg-light">
<div class="container my-5">
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="d-flex justify-content-between mb-4">
<a href="index.php" class="btn btn-outline-primary">
<i class="bi bi-arrow-left"></i> Zurück zum Gästebuch
</a>
<a href="admin.php" class="btn btn-outline-secondary">
<i class="bi bi-shield-lock"></i> Admin-Bereich
</a>
</div>
<?php if (!empty($message)): ?>
<div class="alert alert-success alert-dismissible fade show" role="alert">
<i class="bi bi-check-circle"></i> <?= $message ?>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<?php endif; ?>
<?php if (!empty($error)): ?>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<i class="bi bi-exclamation-circle"></i> <?= $error ?>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<?php endif; ?>
<div class="card mb-5 form-card">
<div class="card-header bg-primary text-white">
<h5 class="mb-0"><i class="bi bi-plus-circle"></i> Neuen Eintrag verfassen</h5>
</div>
<div class="card-body p-4">
<form method="POST" novalidate>
<input type="hidden" name="action" value="add_entry">
<input type="hidden" name="form_start_time" value="<?= time() ?>">
<div class="row">
<div class="col-md-6 mb-3">
<label for="name" class="form-label fw-semibold">Name *</label>
<input type="text" class="form-control form-control-lg" id="name" name="name" required>
</div>
<div class="col-md-6 mb-3">
<label for="email" class="form-label fw-semibold">E-Mail (optional, nur für Admin sichtbar)</label>
<input type="email" class="form-control form-control-lg" id="email" name="email">
</div>
</div>
<div class="honeypot">
<label for="website">Website (nicht ausfüllen)</label>
<input type="text" id="website" name="website" tabindex="-1" autocomplete="off">
</div>
<div class="mb-4">
<label for="comment" class="form-label fw-semibold">Kommentar *</label>
<textarea class="form-control" id="comment" name="comment" rows="5"
placeholder="Schreibe deinen Kommentar" required></textarea>
<div class="mt-2">
<emoji-picker></emoji-picker>
</div>
</div>
<div class="mb-4">
<label for="captcha" class="form-label fw-semibold">Sicherheitscode eingeben *</label>
<div class="row g-3 align-items-center">
<div class="col-6">
<img src="captcha.php" alt="CAPTCHA Bild" class="img-fluid border rounded"
onclick="this.src='captcha.php?v='+Math.random()">
</div>
<div class="col-6">
<input type="text" class="form-control form-control-lg" id="captcha" name="captcha" required>
</div>
</div>
<small class="form-text text-muted mt-2 d-block">
Klicke auf den Code, um das Captcha neu zu laden
</small>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary btn-lg">
<i class="bi bi-send"></i> Eintrag senden
</button>
</div>
</form>
</div>
</div>
<div class="text-center mt-5 pt-4 border-top">
<p class="text-muted">
<i class="bi bi-heart-fill text-danger"></i>
Vielen Dank für Deinen Besuch!
</p>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
<script>
// Emojis einfügen
document.querySelector('emoji-picker')?.addEventListener('emoji-click', event => {
const textarea = document.getElementById('comment');
if (!textarea) return;
const emoji = event.detail.unicode;
const startPos = textarea.selectionStart || 0;
const endPos = textarea.selectionEnd || 0;
textarea.value = textarea.value.substring(0, startPos) + emoji + textarea.value.substring(endPos);
textarea.selectionStart = textarea.selectionEnd = startPos + emoji.length;
textarea.focus();
});
</script>
</body>
</html>
Du benötigst nun auch den sehr bekannten "
PHPMailer", neue Version 6.10.0, den ich dir hier als ZIP-Archiv dazu packe.
Downloaden, entpacken und dann nur das gesamte Verzeichnis mit diesem Namen "
PHPMailer" unverändert auf deinen Server in das gleiche Verzeichnis, in dem dein Projekt liegt, kopieren:
Hier geht es zum direkten Download auf GitHUB (ist aber genau die gleiche Version):
https://github.com/PHPMailer/PHPMailer/ ... ag/v6.10.0