Gammadyne Corporation

Opt-Out Forms

This article explains how to create a form on your website that allows a visitor to unsubscribe from a mailing list.  The form allows a user to enter one key piece of information:  their email address.  The mailing list can be located in a plain-text file, a CSV file, or a database.

The Form
First we will address the opt-out form.  You can either create a new page dedicated to just the form, or the form can be inserted into an existing page.

It is useful to perform some validation of the submitted email address.  If the email address is invalid, the problem is reported in a popup window.  Insert the following code inside your <head> element:

<script language="JavaScript" type="text/javascript">
<!--
// return true if 'e' is a valid simple email address
function validate_email(e) {
    if(e.indexOf('..') >= 0)
        return false;
    if(e.indexOf('<') >= 0)
        return false;
    if(e.indexOf('>') >= 0)
        return false;
    if(e.indexOf('"') >= 0)
        return false;
    if(e.charAt(0)=='.')
        return false;
    if(e.charAt(e.length - 1)=='.')
        return false;
    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);
    }

// validate the form
function validate() {
    var s = document.ourform.email.value;
    if(s==null || s=="") {
        alert('Please enter your email address.');
        document.ourform.email.focus();
        return false;
        }
    if(!validate_email(s)) {
        alert('The email address is not valid.');
        document.ourform.email.focus();
        return false;
        }

    return true;
    }
//-->
</script>


Next, there is the form itself.  This is where the user can enter their email address.

<form action="optout.php" method=post name="ourform" onsubmit="return validate();">
Your email address:<br>
<input size=70 maxlength=80 name=email id=email><br>
<br>
<center><input class=button type=submit value=" Unsubscribe "></center>
</form>


These fields are submitted to a PHP script named "optout.php".  The following sections describe the contents of this script, depending on what type of mailing list you are using.

Plain Text or CSV Mailing List
If your mailing list is a simple, plain-text file with one email address per line, or a CSV file, then the optout.php file looks like this:

<?php
$email = $_REQUEST['email'];
$email_len = strlen($email);
if($email_len < 8 || strpos($email, '@')==false)
    die('Error: the email address is invalid.');

$file = file_get_contents('c:\example\mailing list.txt');
if(!$file)
    die('Error: failed to load mailing list.');

$file_length = strlen($file);
$found = false;
$i = 0;
while(true) {
    $j = stripos($file, $email, $i);
    if($j===false)
        break;
        
    $ch = $file[$j - 1];
    if($ch=="\r" || $ch=="\n" || $ch=='<' || $ch==' ' || $ch=='"' || $j==0) {
        $ch = $file[$j + $email_len];
        if($ch=="\r" || $ch=="\n" || $ch=='>' || $ch==' ' || $ch=='"') {
            // $k is the end of the line
            $k = $j + $email_len;
            while($k < $file_length) {
                $ch = $file[$k];
                if($ch=="\r" || $ch=="\n")
                    break;
                $k += 1;
                }
                
            $ch = $file[$k];
            if($ch=="\r" || $ch=="\n") {
                $k += 1;
                $ch = $file[$k];
                if($ch=="\r" || $ch=="\n")
                    $k += 1;
                }
            
            // move $j to the beginning of the line
            while($j > 0) {
                $ch = $file[$j - 1];
                if($ch=="\r" || $ch=="\n")
                    break;
                $j -= 1;
                }
            
            $file = substr_replace($file, "", $j, $k - $j);
            $found = true;
            $i = $j;
            continue;
            }
        }
        
    $i = $j + $email_len;
    }

if(!$found)
    echo 'Your email address was not found in the mailing list.';
else {
    file_put_contents('c:\example\mailing list.txt', $file);
    echo 'You have been removed from the mailing list.';
    }
?>


Replace both instances of "c:\example\mailing list.txt" with the filepath of your mailing list.

Database Mailing List
If your mailing list is in a database, you will need to install ODBC support into PHP.  For Microsoft IIS, this can be done in IIS Manager > Sites > [your website] > PHP Manager > PHP Extensions > Enable or disable an extension.  You must enable "php_pdo_odbc.dll".

The optout.php file looks like this:

<?php
$email = strtolower($_REQUEST['email']);
$email_len = strlen($email);
if($email_len < 8 || strpos($email, '@')==false)
    die('Error: the email address is invalid.');

// open the database
try {
    $db = new PDO("odbc:Test", "root", "mypassword");
}
catch(PDOException $e) {
    echo "Failed to open database.\r\n" . $e->getMessage();
    return;
    }

// find every occurrence
$rows = array();
$sql = "SELECT pkey, email FROM `test mailing list` WHERE email LIKE '$email'";
foreach($db->query($sql) as $row) {
    if($email==strtolower($row['email']))
        array_push($rows, $row['pkey']);
    }
    
if(count($rows) <= 0)
    die('Your email address was not found in the mailing list.');

// delete each occurrence
foreach($rows as $row) {
    $sql = "DELETE FROM `test mailing list` WHERE pkey=$row";
    if(!$db->query($sql)) {
        echo "<pre>Failed to unsubscribe.\r\n";
        print_r($db->errorInfo());
        echo "</pre>";
        return;
        }
    }

echo 'You have been removed from the mailing list.';
unset($db);
?>


Make the following replacements in the above script:

Replace ThisWith This
my_dsnThe name of the ODBC Data Source.  This must be created in the ODBC Administrator under the "System DSN" tab.
my_userThe user name required for database authentication.
my_passwordThe password required for database authentication.
my_tableThe name of the table that holds the mailing list.
my_email_columnThe name of the column that holds the subscriber's email address.
my_name_columnThe name of the column that holds the subscriber's name.

One-Click Opt-Out
To include a one-click opt-out hyperlink in your marketing emails, the hyperlink would look like this:

<a href="http://example.com/optout.php?email=[[_email]]">Unsubscribe</a>


This example assumes you are using Gammadyne Mailer.  If not, replace [[_email]] with the appropriate merging tag that contains the recipient's email address.

It's also a good idea to put the same URL in a List-Unsubscribe header, like this:

List-Unsubscribe: <http://example.com/optout.php?email=[[_email]]>


Some email clients will use that header to provide the recipient with another method of unsubscribing.  It's better to make it easy for them, so that they do not file a complaint.  Complaints lead to blacklisting.

Two-Click Opt-Out
Alternatively, the opt-out hyperlink can take the recipient to the opt-out form on your website, where they must then click an 'Unsubscribe' button.  The opt-out hyperlink must include the email address in the URL so that the form can be pre-populated.  Here is an example:

<a href="http://example.com/optout.htm?email=[[_email]]">Unsubscribe</a>

This example assumes you are using Gammadyne Mailer.  If not, replace [[_email]] with the appropriate merging tag that contains the recipient's email address.

To pre-populate the form field, you must first add the following Javascript function to the form's <script> element in the <head>:

function getUrlParams() {
    var paramMap = {};
    if(location.search.length==0)
        return paramMap;
    var parts = location.search.substring(1).split("&");
    
    for(var i = 0; i < parts.length; i++) {
        var component = parts[i].split("=");
        paramMap [decodeURIComponent(component[0])] = decodeURIComponent(component[1]);
        }
    return paramMap;
    }


Then, at the bottom of the page after the </html> tag, add the following code:

<script language="JavaScript" type="text/javascript">
<!--
// populate the 'email' parameter
var params = getUrlParams();
document.getElementById('email').value = params.email;
//-->
</script>


See Also
The sister article, Signup Forms, explains how to create a form that subscribes a recipient.

Javascript
PHP
PHP Data Objects (PDO)
ODBC
ODBC Administrator
Gammadyne Mailer

If you find a mistake, please let us know.