For a simple mailinglist, i use phpmailer to send a message to the subscriber with a "unsubscribe link" in it. Inside the link are GET parameters.
I also have a file which unsubscribes a subscriber called: unsubscribe.php
.
The file in which i sent the email with the unsubscribe link is called admin.php
. Both files are in the same directory.
This is part of the code how i send the email with unsubscibe link (admin.php):
$mail->AddAddress($recipients_email, $recipients_name); //Adds a "To" address
// send email with unsubscribe link
try {
$mail->Body = $_POST["message"].'<br /><br />'.'<a href="'.$unsubscribe_path.'unsubscribe.php?id='.urlencode(base64_encode($recipients_id)).'&email='.urlencode(base64_encode($recipients_email)).'&token='.$recipients_token.'">Unsubscribe</a>';
$mail->Send();
$result = '<div class="alert alert-success">Newsletter sent to subscribers of:<b> '.$recipients_category.'</b></div>';
} catch (Exception $e) {
$result = '<div class="alert alert-danger">Mailer Error (' . htmlspecialchars($recipients_email) . ') ' . $mail->ErrorInfo . '</div>';
$mail->smtp->reset(); // reset SMTP connection
}
$mail->clearAddresses(); // Clear all addresses for the next iteration
My unsubscribe.php looks like this:
$id = $_GET['id'];
$email = $_GET['email'];
// decode the id and email string
$id_decode = base64_decode(urldecode($id));
$email_decode = base64_decode(urldecode($email));
$url = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
if ( parse_url($url, PHP_URL_QUERY) != NULL ) { // check if there is a url string with name and email
$filename = 'subscribers/'.$id_decode.'.txt';
// delete subscribers entry
if(file_exists($filename)) {
unlink($filename);
echo '<div class="alert alert-success"><b>'.$email_decode.'</b> is successfully removed from our mailinglist!</div>';
}
else {
echo '<div class="alert alert-danger">Email not found or you already have unsubscribed from our mailinglist!</div>';
}
}
What happens: for some strange reason, every time i send an email to a subscriber, unsubscribe.php
unlinks the subscriber from the list.
While the file unsubscribe.php is only intended if someone clicks on the link in the email!
I figured that out when deleting the file unsubscribe.php
. If i then send an email, the subscriber is not unlinked anymore.
If i send only the message in the email body without the link, the subscriber is also not deleted! So the problem is the link in combination with the unsubscribe.php file
How can i prevent that?
Is the unsubscribe link actually being opened? You can track whether that is happening by adding some logging to your unsubscribe script:
file_put_contents('unsublog.txt', date('Y-m-d h:i:s') . ',' . $id . ',' . $email . ',' . $_SERVER['REMOTE_ADDR'] . "\n", FILE_APPEND | LOCK_EX);
What might be happening is that the receiving server may be opening all links in the message before it is actually read - this is becoming very common in some big providers like gmail. This is done to check the link targets for malware, but of course it also results in immediate unsubscribes in your case.
The way to work around this is to not handle the unsubscribe request immediately, but to make the unsubscribe page request a confirmation first, i.e. so it will require a second request to actually unsubscribe.
Another approach (which you can use at the same time as your manual method) is to support the List-Unsubscribe
message header, along with the associated List-Unsubscribe-Post
header for 1-click functionality. These are defined in RFC2369 and RFC8058 respectively. If you search on those terms you will find lots of tutorials and other resources to help you set it up.