Mailliste med PHP og MySQL (v. 2010-09-26)
Download hele eksemplet som en pakke med køreklar filer mailliste.source.build-20100926.rar. [Downloads: 219]
Om maillisten
Maillisten gør at besøgende kan tilmelde deres e-mailadresse til listen og vil da blive registreret i en database. Listens administrator (måske dig selv) kan så udsende en mail med relevant information til hele listen på en gang. Tilmeldte e-mailadresser forbliver usynlige for hinanden.
Når en bruger tilmelder sig listen tilsendes en autogeneret mail med info til dennes e-mailadresse samt en kopi af samme til administratorens e-mailadresse. Brugere kan også framelde deres e-mailadresse fra samme side og der udsendes i dette tilfælde også en autogeneret e-mail med info om frameldingen. Via den tilhørende administratorside kan administratoren se tilmeldte mailadresser og via en formular udsende mail til hele listen med ønsket emnebeskrivelse og indhold.
MySQL-tabellen til opbevaring af tilmeldte e-mailadresser
Før at maillisten kommer til at virke skal du have oprettet en tabel med følgende struktur i din MySQL-database. Kopiér f.eks. nedenstående SQL-kode og indsæt den i phpMyAdmins SQL-afdeling.
MySQL-tabel til listen
CREATE TABLE IF NOT EXISTS `maillist` ( `id` int(11) NOT NULL auto_increment, `email` varchar(200) NOT NULL, `creation` datetime NOT NULL, PRIMARY KEY (id), UNIQUE (email) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
HTML-formular til til- og frameldinger
Følgende HTML-kode indeholder den formular hvor til- og frameldinger for brugere foregår. Den kan indsættes på en side efter eget valg så den kan indgå pænt i dit hjemmesidedesign. Husk da at ændre henvisningen til siden der viser statusinformation i action-attributten (der hvor der står index.php) - evt. kan det være en og samme side (se koden nedenfor).
index.php
<!-- Til-/afmeldingsformular --><form action="index.php" method="post">
<fieldset>
<legend>Mailliste</legend>
<input type="text" id="email" name="email" value="din@email.dk" /><br />
<input type="submit" id="signUp" name="signUp" value="Tilmeld" />
<input type="submit" id="signDown" name="signDown" value="Frameld" />
</fieldset>
</form>
Visning af maillistesystemet
Siden der viser statusinformation til brugeren ved til- og framelding skal inde holde følgende kode. Koden kan indsættes på en side for sig selv eller på samme side som ovenstående formular.
index.php (fortsat)
<?php
// Inkluderer maillistesystemet
require_once('maillistEngine.php');
// Viser statusinfo til brugere når de til-/framelder sig
if (isset($_REQUEST['signUp'])) {
echo signUp($_POST['email']);
}
if (isset($_REQUEST['signDown'])) {
echo signDown($_POST['email']);
}
?>
Administratorside
Siden der giver mulighed for at udsende besked til alle tilmeldte mailadresser skal indeholde følgende kode. Denne side skal ikke være offentling tilgængelig og bør passwordbeskyttes med f.eks. .htaccess. Se evt. min side om beskyttelse med .htaccess / .htpasswd.).
admin.php
<?php
// Inkluderer maillistesystemet
require_once('maillistEngine.php');
// Kun for administratore: Viser alle tilmeldte mailadresser og mulighed for at maile listen
echo showMaillistAdmin();
?>
Indstillingsfilen
Indtillingsfilen indeholder kode som kan ændres efter behov (filen skal hedde settings.php). Bl.a. kan der indtastes hvad indholdet af mailen sendt til nytilmeldte skal være (se kommentare i koden). Nogle parametere skal ændres til dit eget: dette gælder administrators e-mail, domænenavn, samt MySQL-database brugernavn og password mv.
settings.php
<?php
/**
* PHP and MySQL Maillist System
* Language: Danish
* Version: 2010-09-26 14:00:00
* Author: Christian L. Dünweber
* Webpage: http://www.dunweber.com/docs/scripts/#mailliste
* Copyright (C) 2007-2010 Christian L. Dünweber
* This program is distributed under the GNU General Public License,
* see <http://www.gnu.org/licenses/gpl.html>.
*/
/**
* Følgende indstillinger skal tilpasses din hjemmeside - vær omhyggelig med koden!
*/
// Afsender- og modtageradresse når der skrives til maillistens brugere:
// Denne e-mailadresse vil både være afsender og modtager når der skrives til listen.
// Hertil vil også sendes besked når brugere til- eller afmelder sig listen.
// Brugere på listen modtager mail som BCC for at beskytte deres e-mailadresser.
$maillist_email = 'mailliste@domæne.xx';
// Maillistens navn. Bruges bl.a. som navn vist sammen med ovenstående e-mail:
$maillist_name = 'Mailliste Navn';
// Link til maillistens placering. Bruges bl.a. i mails til listen:
$maillist_link = 'http://www.domæne.xx/mailliste/';
// Ændre følgende fire variabler til at passe med din MySQL-database:
$username = 'user'; //MySQL brugernavn
$password = 'pass'; //MySQL password
$host = 'host'; //MySQL host
$database = 'db'; //MySQL database
// Tabelnavn i MySQL-databasen. Ændre kun hvis du bruger et andet end standard:
$dbTableName = 'maillist';
// Hvor mange e-mails skal der sendes til ad gangen (default 100):
// De enkelte brugere er BCC når der krives til listen for beskyttelse af deres e-mails.
// Justér for at undgå at overskride maksimum antal e-mails i BCC ad gangen i PHPs mail()
// funktion. Hænger sammen med antal tilmeldte på listen og mailserverens indstillnger.
$numEmailsInBcc = 100;
// Tekst i mail til nytilmeldte. E-mail indskydes imellem arrayets to pladser:
$signedup_subject = array("E-mailadressen "," er blevet tilmeldt maillisten hos $maillist_name");
$signedup_message = array("E-mailadressen "," er nu tilmeldt maillisten hos $maillist_name\n\n".
"Velkommen til maillisten!\n\n".
"Du kan framelde din e-mail via følgende link: $maillist_link\n\n".
"Spørgsmål kan rettes til administratoren på $maillist_email.\n".
"Tak for interessen og på genhør.\n\n".
"Mvh.\n".
"Maillisten $maillist_name");
// Tekst i mail til afmeldte. E-mail indskydes imellem arrayets to pladser:
$signeddown_subject = array("E-mailadressen "," er blevet frameldt maillisten hos $maillist_name");
$signeddown_message = array("E-mailadressen "," er nu frameldt maillisten hos $maillist_name.\n\n".
"Farvel og tak,\n\n".
"Du finder os her: $maillist_link\n\n".
"Mvh.\n".
"Maillisten $maillist_name");
// Standard emnebeskrivelse og tekst i mails til hele listen:
$default_subject = "Nyhedsmail fra $maillist_name";
$default_content = "Hej,\n\n".
"Der er ny fra os...\n\n".
"Mvh.\n".
"$maillist_name\n\n".
"Du modtager denne mail fordi du er tilmeldt vores mailliste.\n".
"Du kan framelde din e-mail her: $maillist_link";
?>
Maillistesystemet
Nedenstående boks indeholder koden til maillistesystemet. Dette håndterer til- og frameldinger, administratorfunktioner, samt MySQL-kommunikation. Scriptet kan gemmes i en fil f.eks. med navnet »maillistEngine.php« (skal ende på .php). Læg mærke til at der refereres til denne fil i ovenstående kode.
maillistEngine.php
<?php
/**
* PHP and MySQL Maillist System
* Language: Danish
* Version: 2010-09-26 14:00:00
* Author: Christian L. Dünweber
* Webpage: http://www.dunweber.com/docs/scripts/#mailliste
* Copyright (C) 2007-2010 Christian L. Dünweber
* This program is distributed under the GNU General Public License,
* see <http://www.gnu.org/licenses/gpl.html>.
*/
require_once('mysqlHandler.php');
// Also see file: settings.php
/**
* Function for signing up new users to the maillist. A notification mail is sent
* to new users. A BCC of this is also sent to $maillist_email to notify admin.
* @access public
* @param String with e-mail address to sign up.
* @return HTML string with info on errors or success.
*/
function signUp($email)
{
require('settings.php');
$email = addslashes(trim($email));
if (strcmp($email,'din@email.dk') === 0) {
return '<p>Indtast din e-mailadresse og klik på tilmeld hvis du '.
'ønsker at modtage nyhedsmail fra os.</p>';
}
mysqlConnect();
$info = '';
if (strlen($email) > 0) {
if (checkEmail($email)) {
$result = mysqlQuery("SELECT null FROM $dbTableName WHERE email='$email'");
if (mysql_num_rows($result) > 0) {
$info = '<p>E-mailadressen <em>'.$email.'</em> er '.
'allerede tilmeldt.</p>';
}
else {
$sql = "INSERT INTO $dbTableName (email,creation) VALUES ('$email',NOW())";
$success = mysqlQuery($sql);
if ($success === TRUE) {
$header = "From: $maillist_name <$maillist_email>". "\r\n".
"Bcc: $maillist_email". "\r\n".
"X-Mailer: PHP/".phpversion();
mail($email,
trim(preg_replace("/\n|\r/",' ',implode($email,$signedup_subject))),
trim(wordwrap(implode($email,$signedup_message),70)),
$header);
$info = '<p class="green">Du er nu registreret i maillisten med '.
'e-mailadressen <em>'.$email.'</em>. En mail med info er blevet '.
'sendt til din e-mailadresse.</p>';
}
else {
$info = '<p class="red">Der opstod en mindre fejl - '.
'Prøv at framelde og derefter tilmelde din e-mailadresse igen, '.
'ellers kontakt administrator og meld fejlen.</p>';
}
}
}
else {
$info = '<p class="red">Det lader til at du har angivet ugyldig e-mailadresse. '.
'Tjek at du ikke har tastet forkert og prøv igen, '.
'ellers kontakt administrator og meld fejlen.</p>';
}
}
else {
$info = '<p>Indtastet e-mailadresse.</p>';
}
mysqlClose();
return '<div id="maillistMessage">'.$info.'</div>';
}
/**
* Function for removing users from the maillist. A notification mail is sent
* to the user. A BCC of this is also sent to $maillist_email to notify admin.
* @access public
* @param String with e-mail address to sign up.
* @return HTML string with info on errors or success.
*/
function signDown($email)
{
require('settings.php');
$email = addslashes(trim($email));
$info = '';
if (strcmp($email,'din@email.dk') === 0) {
return '<p>Indtast din e-mailadresse, klik på frameld og du '.
'vil ikke modtage flere nyhedsmails fra os.</p>';
}
mysqlConnect();
if (strlen($email) > 0) {
$result = mysqlQuery("SELECT email FROM $dbTableName WHERE email='$email'");
if (mysql_num_rows($result) > 0) {
$success = mysqlQuery("DELETE FROM $dbTableName WHERE email='$email'");
if ($success === TRUE) {
$header = "From: $maillist_name <$maillist_email>". "\r\n".
"Bcc: $maillist_email". "\r\n".
"X-Mailer: PHP/".phpversion();
mail($email,
trim(preg_replace("/\n|\r/",' ',implode($email,$signeddown_subject))),
trim(wordwrap(implode($email,$signeddown_message),70)),
$header);
$info = '<p class="green">E-mailadressen <em>'.$email.'</em> '.
'er blevet frameldt maillisten. '.
'En bekræftelsesmail er blevet sendt til din e-mailadresse.</p>';
}
else {
$info = '<p class="red">Der opstod en mindre fejl - '.
'Prøv at framelde din e-mailadresse igen, '.
'ellers kontakt administrator og meld fejlen.</p>';
}
}
else {
$info = '<p>E-mailadressen er <em>ikke</em> tilmeldt og '.
'kan derfor ikke frameldes.</p>';
}
}
else {
$info = '<p>Indtastet e-mailadresse.</p>';
}
mysqlClose();
return '<div id="maillistMessage">'.$info.'</div>';
}
//-------------------------------------------------------------
// Administrator functions below
//-------------------------------------------------------------
/**
* Administrators function: Shows all users in the maillist and links to mail
* these separately.
* @access public (but for admins only!)
* @return HTML string with info on errors or success.
*/
function showMaillistAdmin()
{
$emails = getMaillistUsers();
$num = count($emails);
if ($num > 0) {
$emailList = '';
for ($i = 0; $i < $num; $i++) {
$emailList .= '<li class="singleEmail"><a href="mailto:'.$emails[$i].'">'.
$emails[$i].'</a></li>';
}
// Show link to form to mail the list + show individual e-mails on the list
return '<h3>Mail hele listen ('.$num.' tilmeldte)</h3>'.
showMailToMaillistLink($num).
'<h3>Liste med de '.$num.' tilmeldte brugere</h3>'.
'<p>E-mailadresser kan rettes ved at slette og genoprette via '.
'<a href="/mailliste/">til- og afmeldingsformularen</a>.</p>'.
'<ol>'.$emailList.'</ol>';
}
else {
return '<p>Kunne ikke finde nogle tilmeldte e-mailadresser i listen.</p>';
}
}
/**
* Administrators function: Show a form to mail all users on the list collectively.
* @access private
* @param int $numberAssigned The number of users (e-mails) assigned to the maillist.
* @return HTML string with the form or error or success messages.
*/
function showMailToMaillistLink($numberAssigned)
{
require('settings.php');
if (!checkEmail($maillist_email)) {
return '<p class="red">Angiv korrekt administrator e-mail i '.
'»settings.php«</p>';
}
$subject = (isset($_REQUEST['subject'])?trim($_REQUEST['subject']):'');
$message = (isset($_REQUEST['message'])?trim($_REQUEST['message']):'');
if (strlen($subject) == 0) {
$subject = trim($default_subject); // See settings.php for default text
}
if (strlen($message) == 0) {
$message = trim($default_content); // See settings.php for default text
}
$showFormButton =
'<p>Nedenstående knap åbner en formular som kan bruges til at skrive en '.
'mail til hele listen.</p>'.
'<input type="hidden" id="mailAll" name="mailAll" value="1" />'.
'<input type="submit" value="Skriv til maillisten" />';
$mailToAllForm = '<legend class="fancyLegend">Skriv til maillisten</legend>'.
'<label for="from">Fra: </label>'.
'<input type="text" id="from" name="from" size="65" value="'.$maillist_name.
' <'.$maillist_email.'>" disabled="disabled" /><br />'.
'<label for="to">Til: </label>'.
'<input type="text" id="to" name="to" size="65" value="<'.$numberAssigned.
' adresser på listen, usynligt for hinanden>" disabled="disabled" /><br />'.
'<label for="subject">Emne: </label>'.
'<input type="text" id="subject" name="subject" size="65" value="'.$subject.
'" /><br />'.
'<label for="subject">Besked: </label>'.
'<textarea id="message" name="message" cols="70" rows="10">'.$message.
'</textarea><br />'.
'<input type="hidden" class="text" id="mailAll" name="mailAll" value="2" />'.
'<label> </label>'.
'<input type="submit" value="Udsend mail"
onclick="return confirm(\'Mailen afsendes når du klikker OK.\');" />'.
'<input type="reset" value="Annullér" '.
'onclick="window.location=\''.$_SERVER['PHP_SELF'].'\'" />';
$doneButton = '<input type="reset" value="Luk og fortsæt" '.
'onclick="window.location=\''.$_SERVER['PHP_SELF'].'\'" />';
$what = (isset($_REQUEST['mailAll'])?(int)$_REQUEST['mailAll']:0);
$subject_empty = (isset($_REQUEST['subject'])?trim($_REQUEST['subject']):'');
$message_empty = (isset($_REQUEST['message'])?trim($_REQUEST['message']):'');
$formContent = '';
switch($what) {
case 1 : {
// 1: Form with textareas for filling in mail content and sending
$formContent = '<fieldset>'.$mailToAllForm.'</fieldset>';
break;
}
case 2 : {
// 2.1: Send mail to the maillist and show finish button
if (strlen($subject_empty) > 0 && strlen($message_empty) > 0) {
$formContent = '<fieldset>'.
mailToMaillist($subject,$message).$doneButton.'</fieldset>';
}
// 2.2: Inform if one or more fields have been left empty
else {
$formContent = '<fieldset>'.$mailToAllForm.
'<p class="red">'.
'Husk at udfylde både emnebeskrivelse og besked. Default indhold '.
'er blevet indsat automatisk på den manglende plads. Ret til som det '.
'passer dig og prøv igen.</p></fieldset>';
}
break;
}
default : {
// Default: Form with one button to open editable form
$formContent = '<div>'.$showFormButton.'</div>';
break;
}
}
return '<form action="#maillistMailAllForm" method="post" id="maillistMailAllForm">'.
$formContent.'</form>';
}
/**
* Administrators function: Send a mail to all maillist users.
* NB: This may time the server out for large maillist... Need a fix.
* @access private
* @param $subject String with subject of mail to the list.
* @param $message String with messsage of mail to the list.
* @return HTML string with info on errors or success.
*/
function mailToMaillist($subject, $message)
{
require('settings.php');
// Prepare data to be send by e-mail to all maillist users
$subject = preg_replace("/\r|\n/", ' ', $subject);
$message = preg_replace("/\r\n/", "\n", $message); //Lines should only end with newline
$message = wordwrap($message, 70); //Lines should not be longer than 70 characters
// Read in all e-mails on the list and sort them
$maillist = getMaillistUsers();
$numElements = count($maillist);
// Mail $numEmailsInBcc users at a time trying not to exceed maximum allowed in bcc
// This number might be different according to server config
$emails = array_chunk($maillist,$numEmailsInBcc);
$newNum = count($emails);
$errors = array();
@set_time_limit(0); // Turn off max execution time. Only works if safe mode is off
// Mail to users in chunks. Users are set as BCC for privacy
for ($i = 0; $i < $newNum; $i++) {
$bcc = implode(', ',$emails[$i]);
$bcc = preg_replace("/\r|\n/", ' ', $bcc);
$header = "From: $maillist_name <$maillist_email>". "\r\n".
"Bcc: $bcc". "\r\n".
"X-Mailer: PHP/".phpversion();
if (!mail($maillist_email, $subject, $message, $header)) {
$errors[] = $bcc;
}
}
@set_time_limit(30); // Reset to default. Only works if safe mode is off
// Check for mail errors
$num_errors = count($errors);
$error_message = '';
if ($num_errors > 0) {
$error_message = '<p class="red">Der opstod desværre en fejl ved '.
' afsendelsen til visse e-mailadresser. Se følgende:</p>'.
'<ul><li>'.implode('</li><li>',$errors).'</li></ul>';
}
// Show a status message to the admin user
return '<p class="green">Nyhedsmailen blev afsendt til maillisten:</p>'.
'<table>'.
'<tr>'.
'<th valign="top" align="left">Emne:</th>'.
'<td>'.htmlentities($subject,ENT_QUOTES).'</td>'.
'</tr>'.
'<tr>'.
'<th valign="top" align="left">Besked:</th>'.
'<td>'.str_replace("\n",'<br/>',htmlentities($message,ENT_QUOTES)).'</td>'.
'</tr>'.
'</table>'.
$error_message;
}
/**
* Administrators function: Get array of all rows (e-mails) in the maillist table.
* The e-mails are made lower case and sorted ascending.
* @access private
* @return Array with all e-mails in the maillist.
*/
function getMaillistUsers()
{
require('settings.php');
mysqlConnect();
$result = mysqlGetMatrix("SELECT email FROM $dbTableName");
mysqlClose();
for($i = 0; $i < count($result); $i++) {
extract($result[$i]);
$maillist[] = strtolower(trim($email));
}
sort($maillist);
return $maillist;
}
/**
* Check an e-mail address to be on the form x@x.xx or x@x.xxx and check for a DNS
* record of type MX, A, or CNAME for given Internet host name (only works on Windows
* as of PHP 5.3.0).
* @access private
* @param $email String with e-mail address to check.
* @return boolean True if e-mail looks ok and has a valid DNS record, else false.
*/
function checkEmail($email)
{
if ((preg_match('/(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/',$email)) ||
(preg_match('/^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/',$email)))
{
$host = explode('@', $email);
if (function_exists('checkdnsrr')) {
if (checkdnsrr($host[1], 'MX') ||
checkdnsrr($host[1], 'A') ||
checkdnsrr($host[1], 'CNAME')) {
return true;
}
}
else {
return true; // Do not block prior to PHP 5.3.0 on Windows
}
}
return false;
}
?>
MySQL-håndteringsfil
Følgende script håndterer forbindelse og forespørgelser til MySQL-databasen. Scriptet kan gemmes i en fil f.eks. med navnet »mysqlHandler.php« (skal ende på .php).
mysqlHandler.php
<?php
/**
* MySQL-functions to handle connection, requests, and errors.
*
* Use this file by require_once('path_this_file/mysqlHandler.php');
* Call mysqlConnect() to start with.
* Call mysqlQuery() or mysqlGetMatrix() next.
* Call mysqlClose() to stop.
*
* @author NetCafe.dk (closed)
* @rewiser Christian L. Dünweber [www.dunweber.com]
* @version 2008-07-28
*/
// Also see file: settings.php
/**
* Creates connection to MySQL and selects database.
* @param String $database - which database to selelct.
* @todo Change the first four variables to your databae corresponding values.
*/
function mysqlConnect() {
require('settings.php');
if(!checkMySQL()) {
mysqlErrorMessage('<p style="color:red"><strong>Kunne ikke finde PHP\'s MySQL-modul. '.
'Tjek din php-konfiguration</strong></p>');
return;
}
if(!@mysql_connect($host, $username, $password)) {
mysqlErrorMessage('Kunne ikke oprette forbindelse til MySQL');
return;
}
if(!@mysql_select_db($database)) {
mysqlErrorMessage('Kunne ikke vælge databasen: »'.$database.'«');
}
}
/**
* Simply calls the standard mysql_query but makesuse of the error function.
* Suitable for requests that do not return data e.g. INSERT, UPDATE, DELETE, etc.
* @return Resource - MySQL resource on success else false and error function is called.
*/
function mysqlQuery($query) {
$result = mysql_query($query);
if(!$result) {
mysqlErrorMessage('Kunne ikke udfører: »'.$query.'«');
return false;
}
return $result;
}
/**
* Extracts and returns all rows and columns in a table into a matrix (two dimensional array)
* on succes else false.
* Suitable for requests that do return data e.g. SELECT.
* @return String[] - The extracted matrix or false.
*/
function mysqlGetMatrix($query) {
$result = mysql_query($query);
if(!$result) {
mysqlErrorMessage('Kunne ikke udfører: »'.$query.'«');
return false;
}
while(($rowArray = mysql_fetch_array($result)) != FALSE) {
$matrix[] = $rowArray;
}
return $matrix;
}
/**
* Close the connection to the MySQL host and database.
*/
function mysqlClose() {
if(!mysql_close()) {
mysqlErrorMessage('Kunne ikke lukke forbindelsen til MySQL-databasen');
}
}
/**
* Check if PHP has access to the MySQL functions.
*/
function checkMySQL() {
if(function_exists('mysql_connect')) {
return true;
}
return false;
}
/**
* Stop PHP execution and write out MySQL error in HTML.
*/
function mysqlErrorMessage($error) {
$out = '<p><strong style="color:red">MySQL-fejl:</strong> ' . $error;
if($mysqlError = mysql_error()) {
$out .= '.<br /><strong style="color:red">Fejlen er:</strong> <em>'.$mysqlError.
'</em>.</p>';
}
else {
$out .= '.</p>';
}
exit($out);
}
?>
English
Foretrukne
Log ind
Index [scripts]